componentWillRecieveProps方法无法正常工作:ReactJS

时间:2017-06-23 15:31:04

标签: javascript reactjs

以下子组件从其父组件接收道具。然后使用getInitialState将道具设置为自己的状态,并使用this.state将值渲染到相应的输入字段。

我正在使用componentWillRecieveProps在收到新道具时更新子组件的状态。

最初在调用组件时,它可以正常工作。当它第二次传递道具时会出现问题,触发道具传递的相应按钮需要两次点击来设置孩子的状态。

我可能错误地使用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,
  })
},

完整代码:

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;     

1 个答案:

答案 0 :(得分:7)

  

我可能错误地使用componentWillRecieveProps?

是的,因为你需要使用props.keyname(传递参数的道具 这个方法),而不是this.props中的componentWillReceiveProps

原因是,在此lifecycle方法this.props中,props方法lifecycle将使之前的this.props值不是新值props新的componentWillReceiveProps值。

根据DOC

  

在安装的组件之前调用componentWillReceiveProps()   收到新的道具。如果您需要更新状态以响应   prop更改(例如,重置它),您可以比较this.props   和nextProps并使用this.setState()执行状态转换   这种方法。

这是因为setState将为父级内的每个newprops调用,因此在首先在子组件内设置state之前,我们应该比较prev值和新值,可能在里面parent其他console.log值已更改,而不是我们传递给子组件的值。

this.propsnewPropscomponentWillReceiveProps: 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 }, 并检查结果。

使用此:

import requests
import json

auth_url = "http://learn.ZZZZZZZ.com/oauth2/authorize"

#credential
auth_client_id = "BBBBBBBBBBBBBBBBBBBBBBBB"
auth_client_secret = "YYYYYYYYYYYYYYYYYYYYY"  

payload={'grant_type':'client_credentials', 'client_id':auth_client_id,'client_secret':auth_client_secret}
headers={'Accept':'application/json', 'Content-Type':'application/x-www-form-urlencoded'}

response = requests.post(auth_url,headers=headers,data=payload)
response.text