从 props 中反应未定义的 setState
React undefined setState from props
我有两个组件:Orders
和 FormDialog
,第一个是第二个的父亲。
我正在尝试将数据作为属性从 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 之后,由于第一个错误而未初始化。
两期:
您的呈现方法正在尝试使用尚未初始化的状态呈现 FormDialog。状态将是 undefined 直到你在构造函数中设置它,如:
constructor(props) {
super(props);
this.state = {
order: this.props.order,
}
}
由于您只是从父组件传递一个 prop,这足以无错地渲染组件。这样你就不需要调用 componentDidMount 或者,在你的情况下,componentWillMount,并且可以完全删除它。
- 您在未安装的组件中调用 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() 应该有效。
不过不用担心,将组件更改为功能组件后,它不应该出现。
我有两个组件:Orders
和 FormDialog
,第一个是第二个的父亲。
我正在尝试将数据作为属性从 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 之后,由于第一个错误而未初始化。
两期:
您的呈现方法正在尝试使用尚未初始化的状态呈现 FormDialog。状态将是 undefined 直到你在构造函数中设置它,如:
constructor(props) { super(props); this.state = { order: this.props.order, } }
由于您只是从父组件传递一个 prop,这足以无错地渲染组件。这样你就不需要调用 componentDidMount 或者,在你的情况下,componentWillMount,并且可以完全删除它。
- 您在未安装的组件中调用 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() 应该有效。
不过不用担心,将组件更改为功能组件后,它不应该出现。