简体   繁体   English

从道具反应未定义的setState

[英]React undefined setState from props

I've two componentes: Orders and FormDialog , the first is father of the second. 我有两个组件: OrdersFormDialog ,第一个是第二个的父亲。 I've trying to send data as properties from Orders to FormDialog as follows: 我试图将数据作为属性从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 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>
  )}

This display TypeError: this.state.order is undefined when try to compile. 尝试编译时,此显示TypeError: this.state.order is undefined Any suggestion? 有什么建议吗?

Two issues: 两个问题:

  1. Your render method is trying to render a FormDialog using state which isn't initialized yet. 您的render方法正在尝试使用尚未初始化的状态来渲染FormDialog。 State will be undefined until you set it inside constructor like: 状态将是不确定的,直到您在构造函数中将其设置为:

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

Since you're just passing down a prop from the parent component, this will be enough to render the component without errors. 由于您只是从父组件传递了一个prop,因此足以渲染该组件而不会出错。 This way you don't need to call componentDidMount or, in your case, componentWillMount , and can remove it altogether. 这样,您无需调用componentDidMount ,也无需调用componentWillMount ,并且可以将其完全删除。


  1. You're calling setState in an unmounted component, which will always result in an error in React. 您在未安装的组件中调用setState ,这将始终在React中导致错误。 As its name suggests, componentWillMount is called right before the component mounts and you should be using componentDidMount instead to make sure the component is mounted before calling setState . 顾名思义, componentWillMount在组件安装之前被调用,您应该使用componentDidMount来确保在调用setState之前已安装组件。

Also, componentWillMount has been deprecated in newer versions of React and is no longer recommended to be used in code. 另外,在较新版本的React中不建议使用componentWillMount ,因此不建议在代码中使用它。

From React official documentation 从React官方文档


Additional note, it seems to me that you have unnecessary duplication of state in these two components. 另外请注意,在我看来,您在这两个组件中具有不必要的状态重复。 Consider keeping the order data only in the FormDialog component since it will probably be the only component updating order data. 考虑将订单数据仅保留在FormDialog组件中,因为它可能是唯一更新订单数据的组件。

super(props), not super( ...props) same for constructor super(props),而不是super(... props)与构造函数相同

This link to the doc shows the proper way 此指向文档的链接显示了正确的方法

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

Just after the constructor, the code is still correct but after componentWillMount state.order is replaced by this.props.order which is not initialised due to the first error. 就在构造函数之后,代码仍然是正确的,但是在componentWillMount state.order被this.props.order替换之后,由于第一个错误而未初始化。

You should avoid state duplication, you can make FormDialog stateless component, maybe even function component. 您应该避免状态重复,可以使FormDialog成为无状态组件,甚至可以使函数组件成为无状态。 Remember to use as many stateless component as possible. 记住要使用尽可能多的无状态组件。

import React from 'react';

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

export default FormDialog;

Regardless, it looks like your TypeError error appears because you 无论如何,看起来是因为您出现TypeError错误

(1) Typo, it should be a (1)错字,应该是

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

or just 要不就

state= bla bla bla ... 

like you did in Orders component 就像您在“订单”组件中所做的一样

(2) Tried calling setstate before the component mounted. (2)在安装组件之前尝试调用setstate。 Change async componentWillMount() to componentDidMount() should works. 将异步componentWillMount()更改为componentDidMount()应该可以工作。

But don't worry about that, after you change the component to function component it shouldn't appear. 但是不必担心,在将组件更改为功能组件后,它不应出现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM