【问题标题】:React Error: Nothing was returned from render反应错误:渲染没有返回任何内容
【发布时间】:2019-07-31 23:25:54
【问题描述】:

注意:我已经看过类似的问题;提供的解决方案不能解决我的问题。

我的 React 应用程序出现以下错误

TasksColumn(...):渲染没有返回任何内容。这通常 > 意味着缺少 return 语句。或者,不渲染任何内容,返回 >null。

以下是相关代码:

TasksColumn.js

import React, { Component } from "react";
import { render } from "react-dom";
import { Col, Row } from "react-bootstrap";

const taskData = [
  {
    title: "Preliminary Report",
    course: "Capstone Design",
    type: "Report",
    deadline: "2019-10-04"
  },
  {
    title: "title2",
    course: "course2",
    type: "type2",
    deadline: "date2"
  },
  {
    title: "title3",
    course: "course3",
    type: "type3",
    deadline: "deadline3"
  }
];

const TaskRecord = ({ title, course, type, deadline }) => {
  return (
    <Row class="task-record">
      <Col>
        <div class="task-record-title">
          <h5>{title}</h5>
        </div>
        <div class="task-record-course">
          <h6>{course}</h6>
        </div>
      </Col>
      <Col>
        <div class="task-record-type">
          <p>{type}</p>
        </div>
        <div class="task-record-deadline">
          <p>{deadline}</p>
        </div>
      </Col>
    </Row>
  );
};

export default class TasksColumn extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: false,
      mounted: false,
      data: []
    };
  }
  componentDidMount() {
    this.setState({
      isLoading: true,
      mounted: true
    });
  }
  render() {
    const { tasks } = this.props;
    let mounted = this.state.mounted;

    if (mounted == true) {
      return (
        <Col id="tasks-column">
          {tasks.map((task, i) => (
            <TaskRecord
              key={i}
              title={task.title}
              course={task.course}
              type={task.type}
              deadline={task.deadline}
            />
          ))}
        </Col>
      );
    }
  }
}

render(<TasksColumn tasks={taskData} />, document.querySelector("#root"));

Dashboard.js

import React from "react";
import { Container, Row, Col } from "reactstrap";
import TasksColumn from "../../molecules/TasksColumn";

export default function Dashboard(props) {
  return (
    <React.Fragment>
      <Container>
        <Row>
          <TasksColumn />
        </Row>
      </Container>
    </React.Fragment>
  );
}

作为最终结果,我需要 Dashboard.js 中的 TasksColumns 在 TaskRecord 中呈现每个 taskData。

【问题讨论】:

  • 您好,R.Antao,请在下面查看我的解决方案,如果可行,请告诉我。

标签: reactjs


【解决方案1】:

您的问题是TaskColumn 类,特别是render 方法:

class TaskColumn extends React.Component {
  render() {
    const mounted = this.state.mounted

    // DON'T DO THIS
    if (mounted == true) {
      return (...)
    }
  }
}

根据React.js 文档:

componentDidMount() 在组件被挂载(插入到树中)后立即调用

由于您的render 函数仅在mounted 为true 时返回JSX,因此本质上您在mounted 为false 时返回undefined。这发生在您的组件第一次挂载时(在componentDidMount 被触发之前)并且是错误的,因为render 函数必须返回以下任何内容:

  • 反应元素
  • 数组和片段
  • 门户
  • 字符串和数字
  • 布尔值或空值

查看此处了解更多信息:reactjs.org/docs/react-component.html#render。

如果你不想在满足某个条件之前渲染任何东西,你应该返回null:

class TaskColumn extends React.Component {
  render() {
    const { tasks } = this.props
    const isLoading = this.state.isLoading

    if (isLoading) {
      return <h1>Loading</h1>
    }
    if (!isLoading && tasks && tasks.length > 0) {
      return (
        <Col>
         {tasks.map(...)}
        </Col>
      )
    }
    // otherwise return null if you don't want to 
    // show anything until data/tasks become available
    return null
  }
}

【讨论】:

    【解决方案2】:

    在您的TaskColumn 组件中,当前您仅在mounted 为true 时才返回某些内容。但是直到您在componentDidMount() 中的逻辑之前,mounted 才设置为true。 componentDidMount() 仅在第一次渲染后触发。您仍然需要 return 一些东西,以便安装时的 initial 渲染仍然是 false:

    export default class TasksColumn extends Component {
         constructor(props) {
              super(props);
              this.state = {
                   isLoading: false,
               mounted: false,
               data: []
              };
         }
         componentDidMount() {
              this.setState({
               isLoading: true,
            mounted: true
              });
         }
         render() {
              const { tasks } = this.props;
          let mounted = this.state.mounted;
    
              if (mounted == true) {
               return ( 
                    <Col id="tasks-column">
                     {tasks.map((task, i) => 
                      <TaskRecord 
                           key={i}
                       title={task.title} 
                           course={task.course} 
                       type={task.type}
                       deadline={task.deadline}
                      />
                     )}
                 </Col>
               );  
             } else {
                return <div>woof</div>
             }
         }
    }
    

    【讨论】:

    • 添加 else {return null}(或 woof),成功了!谢谢克里斯。
    • @R.Antao 欢迎您的朋友!请考虑将此标记为解决方案:)
    【解决方案3】:

    您正在使用与渲染方法冲突的 react DOM 的渲染名称。

    从 'react-dom' 导入 ReactDOM;

    ReactDOM.render (
        <TasksColumn tasks={taskData}/>, 
        document.querySelector("#root")
    );
    

    【讨论】:

      【解决方案4】:

      您应该将taskData 作为道具传递给您调用它的taskColumn,即Dashboard。这是更好的做法,因为这样,“调用者”组件控制其子组件。以这种方式设置更清晰,更具可读性。 React 一直都是这样——所有关于模块化、分解事物和保持数据流的清洁。阅读此处了解更多信息:https://reactjs.org/docs/thinking-in-react.html。

      你不需要

      render (
          <TasksColumn tasks={taskData}/>, 
          document.querySelector("#root")
      )
      

      在组件之外,因为您现在已经设置了所有这些组件 单独的渲染方法。

      其他说明: 到目前为止,您的用例可能不需要两个状态变量来“安装”/“加载”。只需使用 PropTypes 设置默认值(或设为必需)taskData。示例:

      TasksColumn.propTypes = {
        taskData: PropTypes.arrayOf(PropTypes.shape({
          title: PropTypes.string,
          course: PropTypes.string,
          type: PropTypes.string,
          deadline: PropTypes.string,
        }))
      };
      
      TasksColumn.defaultProps = {
        taskData: [
          {
            title: '',
            course: '',
            type: '',
            deadline: '',
          },
        ],
      };
      

      【讨论】:

        猜你喜欢
        • 2020-06-25
        • 1970-01-01
        • 1970-01-01
        • 2020-11-27
        • 2020-09-14
        • 2018-04-05
        • 2020-09-06
        • 2021-01-01
        • 2019-04-14
        相关资源
        最近更新 更多