从道具反应未定义的setState

时间:2019-03-07 23:49:21

标签: javascript reactjs react-props react-state

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

  

订单组件

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组件

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。有什么建议吗?

3 个答案:

答案 0 :(得分:2)

两个问题:

  1. 您的render方法正在尝试使用尚未初始化的状态来渲染FormDialog。状态将是未定义,直到您在构造器中设置它,例如:

    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组件中,因为它可能是唯一更新订单数据的组件。

答案 1 :(得分:1)

super(props),而不是super(... props) 对于构造函数

此文档链接显示了正确的方法

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

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

答案 2 :(得分:0)

您应该避免状态重复,可以使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。将异步componentWillMount()更改为componentDidMount()应该可以。

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