从 props 中反应未定义的 setState

React undefined setState from props

我有两个组件:OrdersFormDialog,第一个是第二个的父亲。 我正在尝试将数据作为属性从 Orders 发送到 FormDialog,如下所示:

Orders Component

class Orders extends Component {
 state={
    open: false,
    order: {
      address: '',
      client: '',
      date: '',
      estimated_time: '',
      id: 0,
      order_no: '',
      original_order_no: '',
      phone: '',
      place: '',
      position: '',
      status: '',
      team: ''
    }
  }
 render() {
    return (
      <div>
        <FormDialog open={this.state.open} order={this.state.order}/>
      </div>
    );
  }

FormDialog Component

export default class FormDialog extends React.Component {

  constructor(...props) {
    super(...props);
    this.state = {
      order: {
        address: '',
        client: '',
        date: '',
        estimated_time: '',
        id: 0,
        order_no: '',
        original_order_no: '',
        phone: '',
        place: '',
        position: '',
        status: '',
        team: ''
      }
    };
  }
  async componentWillMount()
    this.setState({order: this.props.order})
  };
  render() {
    return (
      <div>{this.state.order.team}</div>
  )}

编译时显示TypeError: this.state.order is undefined。有什么建议吗?

super(props),不是 super( ...props) 构造函数相同

文档中的 link 显示了正确的方法

https://reactjs.org/docs/react-component.html#constructor

在构造函数之后,代码仍然正确,但在 componentWillMount state.order 被替换为 this.props.order 之后,由于第一个错误而未初始化。

两期:

  1. 您的呈现方法正在尝试使用尚未初始化的状态呈现 FormDialog。状态将是 undefined 直到你在构造函数中设置它,如:

    constructor(props) {
        super(props);
    
        this.state = {
            order: this.props.order,
        }
    }
    

由于您只是从父组件传递一个 prop,这足以无错地渲染组件。这样你就不需要调用 componentDidMount 或者,在你的情况下,componentWillMount,并且可以完全删除它。


  1. 您在未安装的组件中调用 setState,这将始终导致 React 出错。顾名思义,componentWillMount 在组件挂载之前调用,您应该使用 componentDidMount 来确保组件在调用 setState.

此外,componentWillMount 已在较新版本的 React 中弃用,不再建议在代码中使用。

From React official documentation


补充说明,在我看来,您在这两个组件中有不必要的状态重复。考虑只在 FormDialog 组件中保留订单数据,因为它可能是唯一更新订单数据的组件。

你应该避免状态重复,你可以让 FormDialog 成为无状态组件,甚至是函数组件。记得尽可能多地使用无状态组件。

import React from 'react';

const FormDialog = props => {
  return (
    <div>
      {props.order.team}
    </div>
  );
};

export default FormDialog;

无论如何,您的 TypeError 错误似乎是因为您

(1) 打字错误,应该是

constructor (props) {
super (props);
this.state = bla bla bla ...;
  }

state= bla bla bla ... 

就像您在订单组件中所做的那样

(2) 尝试在安装组件之前调用 setstate。将 async componentWillMount() 更改为 componentDidMount() 应该有效。

不过不用担心,将组件更改为功能组件后,它不应该出现。