react错误:渲染没有返回任何内容

IT技术 reactjs
2021-05-20 01:37:33

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

我的 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>
  );
}

作为一个最终的结果,我需要TasksColumnsDashboard.js渲染每个taskData里面TaskRecord

4个回答

你的问题是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函数仅返回JSXwhen mountedis true,因此实际上您正在返回undefinedwhen mountedis false当您的组件第一次挂载时(在componentDidMount被触发之前会发生这种情况并且是错误的,因为该render函数必须返回以下任何一项:

  • react元素
  • 数组和片段
  • 传送门
  • 字符串和数字
  • 布尔值或 null

看看这里阅读更多: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
  }
}

在您的TaskColumn组件中,目前您只在mountedis时返回一些东西true但是true直到您在componentDidMount(). componentDidMount()仅在第一次渲染后触发。当安装仍然是时,您仍然需要return初始渲染一些事情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>
         }
     }
}

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

从 'react-dom' 导入 ReactDOM;

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

您应该taskData作为props传递taskColumn您调用它的地方,即在Dashboard. 这是更好的做法,因为这样,“调用者”组件控制其子组件。以这种方式设置它更干净,更易读。React 一直都是这样 - 所有关于module化和分解事物并保持数据流干净。阅读此处了解更多信息: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: '',
    },
  ],
};