ComponentWillRecieveProps method is not working correctly: ReactJS
The next child component receives props from its parent. It then sets the props to their own state with getInitialState
and maps the value to the appropriate input fields with this.state
.
I use componentWillRecieveProps
to update the state of the child component when it receives new props.
Initially, when a component is called, it works correctly. This issue occurs when it passes props a second time, the corresponding button that triggers props has to be done with two clicks to set the child state.
Am I potentially misusing componentWillRecieveProps
?
getInitialState: function() {
return {
pitch: this.props.booking.pitch,
email: this.props.booking.email,
firstName: this.props.booking.firstName,
arrivalDate: this.props.booking.arrivalDate,
}
},
componentWillReceiveProps: function (props) {
this.setState({
pitch: this.props.booking.pitch,
email: this.props.booking.email,
firstName: this.props.booking.firstName,
arrivalDate: this.props.booking.arrivalDate,
})
},
Complete code:
var React = require('react');
var createReactClass = require('create-react-class');
var ViewBooking = createReactClass({
getInitialState: function() {
return {
pitch: this.props.booking.pitch,
email: this.props.booking.email,
firstName: this.props.booking.firstName,
arrivalDate: this.props.booking.arrivalDate,
}
},
componentWillReceiveProps: function (props) {
this.setState({
pitch: this.props.booking.pitch,
email: this.props.booking.email,
firstName: this.props.booking.firstName,
arrivalDate: this.props.booking.arrivalDate,
})
},
_handleInputChange: function(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
var partialState = {};
partialState[name] = value;
console.log(partialState);
this.setState(partialState);
},
_handleUpdateClose: function(e) {
this.props.updateClose();
e.preventDefault();
},
_handleUpdateBooking: function (e) {
var tempBooking = {
pitch: this.state.pitch,
email: this.state.email,
firstName: this.state.firstName,
arrivalDate: this.state.arrivalDate,
}
this.props.updateBooking(tempBooking);
e.preventDefault();
},
_handleDelete: function (e) {
this.props.deleteBooking();
e.preventDefault();
},
render: function() {
if (this.props.viewFormVisibility) {
formVisibility = {"display": "block"};
} else {
formVisibility = {"display": "none"};
}
return (
<div>
<form style={formVisibility}>
<h4>View Booking</h4>
<div className="form-group row">
<label className="col-2 col-form-label">Pitch</label>
<div className="col-10">
<input value={this.state.pitch} onChange={this._handleInputChange} className="form-control" name="pitch" ref="inputPitch" type="number" id="example-number-input"/>
</div>
</div>
<div className="form-group row">
<label className="col-2 col-form-label">First Name</label>
<div className="col-10">
<input value={this.state.firstName} onChange={this._handleInputChange} className="form-control" ref="firstName" name="firstName" type="text" id="example-text-input"/>
</div>
</div>
<div className="form-group row">
<label className="col-2 col-form-label">Email</label>
<div className="col-10">
<input value={this.state.email} onChange={this._handleInputChange} className="form-control" ref="inputEmail" type="email" name="email" id="example-email-input"/>
</div>
</div>
<div className="form-group row">
<label className="col-2 col-form-label">Date</label>
<div className="col-10">
<input value={this.state.arrivalDate} onChange={this._handleInputChange} className="form-control" ref="arrivalDate" name="arrivalDate" type="date" id="example-date-input"/>
</div>
</div>
<button type="submit" className="btn btn-primary" onClick={this._handleUpdateBooking}>Save changes</button>
<button className="btn btn-danger" onClick={this._handleUpdateClose}>Close</button>
<button onClick={this._handleDelete} className="btn btn-danger">Delete</button>
</form>
</div>
)
}
})
module.exports = ViewBooking;
source to share
Am I potentially misusing componentWillRecieveProps?
Yes, because you need to use props.keyname
(props the passed parameter to this method) instead of this.props
in componentWillReceiveProps
.
The reason is that inside this method the lifecycle
this.props
previous values props
will not be new, after that the lifecycle
method this.props
will have new values props
.
By DOC :
componentWillReceiveProps () is called before the connected component receives new props. If you need to update the state in response to (for example, before resetting it), you can compare this.props and nextProps and perform state transitions using this.setState () in that method.
This is due to what componentWillReceiveProps
will be called for each one setState
inside the parent, so before setting the inner child component newprops
, we first have to compare the prev value and the new value, maybe inside the parent some other state
value was changed by something other than the one we pass to the child component.
Take console.log
on this.props
and newprops
and check the result.
Use this:
componentWillReceiveProps: function (newProps) {
this.setState({
pitch: newProps.booking.pitch,
email: newProps.booking.email,
firstName: newProps.booking.firstName,
arrivalDate: newProps.booking.arrivalDate,
})
console.log('previous value', this.props); //print the previous values
console.log('new values', newProps); //new values
},
source to share