【问题标题】:Render method should have a return statement. Fetch data via mongoose渲染方法应该有一个返回语句。通过猫鼬获取数据
【发布时间】:2021-02-04 16:31:33
【问题描述】:

我正在学习 ReactJS、NodeJS、ExpressJS 并构建一个页面,您可以在其中向提要(通过 API 的 mongoDB 数据库)提交内容(帖子),刷新页面后,您会在输入文本的表单下方看到帖子.

我收到以下错误: "编译失败 ./src/components/this_file.js 第 22:3 行:你的渲染方法应该有 return 语句 react/require-render-return 搜索关键字以了解有关每个错误的更多信息。"

谁能解释或提供一篇文章,从中我可以了解我做错了什么以及如何解决这个渲染问题? 因为据我所见,我在渲染后确实有一个返回语句。

代码如下:

import React, { useState, useEffect } from "react";
import { Container} from 'react-bootstrap'
import Layout from '../components/layout'
import { Helmet } from 'react-helmet'
import styles from './layout.module.css'
import Form from 'react-bootstrap/Form'
import Button from 'react-bootstrap/Button'
import Card from 'react-bootstrap/Card'

// SERVICES
import productService from '../services/productService';

class App extends React.Component {
  
  constructor(props) {
    super(props);
    this.state = {
      content: ''
    }
  }

  render() {

    const [feeds, setfeed] = useState(null);

useEffect(() => {
  if(!feeds) {
    getContent();
  }
})


const getContent = async () => {
  let res = await productService.getFeed();
  console.log(res);
  setfeed(res);
}

const renderFeed = feed => {
  return (
        <>
        <Layout>
        <Helmet>
        <title>Feed</title>
        </Helmet>
        <Container>

        <br /><br /><br />
        {/* <h5>Start typing...</h5> */}

        <form id="feed-form" onSubmit={this.handleSubmit.bind(this)} method="POST">

        <Form.Group>

         <Form.Control
            as="textarea"
            rows="10"
            name="feed"
            style={{ backgroundColor: 'gray'}}
            value={this.state.message}
            onChange={this.onMessageChange.bind(this)}
          />
          <Form.Text className="text-muted">
            Post visible after page refresh.
          </Form.Text>
          
        </Form.Group>

          <Button type="submit" style={{ backgroundColor: 'gray', border: 'grey' }}> 
            Submit
          </Button>
          
        </form><br />

        <Card border="dark" text="light" key={feed._id}>
        <Card.Body>
            {feed.content}<br /><br />
          <Card.Text className="text-right">
            <small className="text-muted">{formatDate(feed.date)}</small>
          </Card.Text>
        </Card.Body>
        </Card>
        <br />

        {(feeds && feeds.length > 0) ? (
          feeds.map(feed => renderFeed(feed))
        ) : (
          <p>No feed found</p>
        )}

<div className={styles.backToHome}>
      <a href="/" className="link">
        ← Back to home
      </a>
    </div>
        </Container>
        </Layout>
        </>
  );
}
  }

  onMessageChange(event) {
    this.setState({content: event.target.value})
  }

  handleSubmit(e) {
    e.preventDefault();
  
    fetch('http://localhost:3000/api/feed', {
        method: "POST",
        body: JSON.stringify(this.state),
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
      }).then(
      (response) => (response.json())
        ).then((response)=> {
      if (response.status === 'success') {
        alert("Message Sent."); 
        this.resetForm()
      } else if(response.status === 'fail') {
        alert("Message failed to send.")
      }
    })
  }
}

function formatDate( string ) {
  var options = { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' };
  return new Date( string ).toLocaleDateString([], options);
}

export default App;

谢谢你????

【问题讨论】:

  • 正如错误所说,您的 render() 方法没有返回任何内容。您在 render 方法中定义的函数中有 return 语句,但不会为 render 方法本身做 return
  • 你的render() { 函数,在contructor() 下的声明应该在类组件的最后,并且里面应该只有你想要渲染到屏幕上的jsx。跨度>
  • 另一个关键问题是像useEffect这样带有类组件的钩子,它们只能与功能组件一起使用。

标签: javascript reactjs mongodb mongoose react-bootstrap


【解决方案1】:

看起来您的主要问题是您使用了基于类的组件和功能组件的混合方法,我建议您先修复。

例如,这是在基于类的组件中设置状态的方式:

constructor(props) {
    super(props);
    this.state = {
      content: ''
    };
  }

这就是您在功能组件中设置它的方式。

const [feeds, setfeed] = useState(null);

但是,您可以将两者结合起来。您需要决定是否需要类组件或功能组件。

例如,如果您想使用 useStateuseEffect 挂钩,则需要将其转换为功能组件。

Here is an explanation of the difference between the two

此外,在 render() 函数内部,您不会返回任何内容。

您确实有一个带有 return 语句的 renderFeed 函数,但该 return 语句不在 render() 函数的范围内。

【讨论】:

    【解决方案2】:

    感谢所有答案。

    这是最终的形式,bois:

    import React, { useState, useEffect } from "react";
    import { Container} from 'react-bootstrap'
    import Layout from '../components/layout'
    import { Helmet } from 'react-helmet'
    import styles from './layout.module.css'
    import Form from 'react-bootstrap/Form'
    import Button from 'react-bootstrap/Button'
    import Card from 'react-bootstrap/Card'
    
    class App extends React.Component {
      
      constructor(props) {
        super(props);
        this.state = {
          contents: []
        }
      }
    
      state = {
        hasErrors: false,
        content: {}
      };
    
      componentDidMount() {
        fetch("http://localhost:3000/api/feed")
          .then(res => res.json())
          .then(res => this.setState({ contents: res }))
          .catch(() => this.setState({ hasErrors: true }));
      }
    
      render() {
    
        const { contents } = this.state
    
      return (
            <>
            <Layout>
            <Helmet>
            <title>Feed</title>
            </Helmet>
            <Container>
    
            <br /><br /><br />
            {/* <h5>Start typing...</h5> */}
    
            <form id="feed-form" onSubmit={this.handleSubmit.bind(this)} method="POST">
    
            <Form.Group>
    
             <Form.Control
                as="textarea"
                rows="10"
                name="feed"
                style={{ backgroundColor: 'gray'}}
                value={this.state.message}
                onChange={this.onMessageChange.bind(this)}
              />
              <Form.Text className="text-muted">
                Post visible after page refresh.
              </Form.Text>
              
            </Form.Group>
    
              <Button type="submit" style={{ backgroundColor: 'gray', border: 'grey' }}> 
                Submit
              </Button>
              
            </form><br />
    
            {contents.map((item, index) => 
           <> <Card border="dark" text="light">
                          
                              <Card.Body>
                                  {item.content}<br /><br />
                                <Card.Text className="text-right">
                                  <small className="text-muted">{formatDate(item.date)}</small>
                                </Card.Text>
                              </Card.Body>
                          
                            </Card><br/></>
            )}
    
    <div className={styles.backToHome}>
          <a href="/" className="link">
            ← Back to home
          </a>
        </div>
            </Container>
            </Layout>
            </>
      );
    }
    
      onMessageChange(event) {
        this.setState({content: event.target.value})
      }
    
      handleSubmit(e) {
        e.preventDefault();
      
        fetch('http://localhost:3000/api/feed', {
            method: "POST",
            body: JSON.stringify(this.state),
            headers: {
              'Accept': 'application/json',
              'Content-Type': 'application/json'
            },
          }).then(
          (response) => (response.json())
            ).then((response)=> {
          if (response.status === 'success') {
            alert("Message Sent."); 
            this.resetForm()
          } else if(response.status === 'fail') {
            alert("Message failed to send.")
          }
        })
      }
    }
    
    function formatDate( string ) {
      var options = { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' };
      return new Date( string ).toLocaleDateString([], options);
    }
    
    export default App;
    

    按预期工作。

    【讨论】:

      【解决方案3】:

      在你的渲染方法中返回一些东西......例如

      class App extends React.Component {
        
        constructor(props) {
          super(props);
          this.state = {
            content: ''
          }
        }
      
        render() {
         return (<renderFeed/>)
      }
      

      但是您的类组件class App extends React.Component 正在使用混合的函数组件方法,这是不允许的。要么将 App 组件重构为功能组件,要么使用“经典”生命周期方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-14
        • 2020-12-27
        • 1970-01-01
        • 2010-09-07
        • 2019-03-25
        • 1970-01-01
        相关资源
        最近更新 更多