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;     
      

Run code


+3


source to share


1 answer


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
},

      

+6


source







All Articles