Reputation: 297
I've two componentes: Orders
and FormDialog
, the first is father of the second.
I've trying to send data as properties from Orders
to FormDialog
as follows:
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>
)}
This display TypeError: this.state.order is undefined
when try to compile. Any suggestion?
Upvotes: 1
Views: 2631
Reputation: 544
Two issues:
Your render method is trying to render a FormDialog using state which isn't initialized yet. 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. This way you don't need to call componentDidMount or, in your case, componentWillMount, and can remove it altogether.
Also, componentWillMount has been deprecated in newer versions of React and is no longer recommended to be used in code.
From React official documentation
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.
Upvotes: 2
Reputation: 9
You should avoid state duplication, you can make FormDialog stateless component, maybe even function component. 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
(1) Typo, it should be a
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. Change async componentWillMount() to componentDidMount() should works.
But don't worry about that, after you change the component to function component it shouldn't appear.
Upvotes: 0
Reputation: 11
super(props), not super( ...props) same for constructor
This link to the doc shows the proper way
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.
Upvotes: 1