React孩子收到旧状态道具,没有更新状态道具

时间:2018-01-31 14:17:02

标签: arrays reactjs state

我有一个时髦的设置。我需要一个多阶段登记表。我有父母:

class ContactPage extends React.Component {
constructor(props){
    super(props);
    this.state = {
        stage:0,
        name:'',
        message:'',
        email:'',
        phone:''
    }
    this.setName=(e)=>{
        this.setState({name:e});
    }
    this.setMessage=(e)=>{
        this.setState({message:e});
    }
    this.setEmail=(e)=>{
        this.setState({email:e});
    }
    this.setPhone=(e)=>{
        this.setState({phone:e});
    }

    this.nextStage=()=>{
        if(this.state.stage < 3){
            this.setState({stage:this.state.stage+1})
        }
    }
    this.previousStage=()=>{
        if(this.state.stage >= 1){
            this.setState({stage:this.state.stage-1})
        }
    }
    this.stage = [
        <ContactName onChange={this.setName} />,
        <ContactInfo />,
        <ContactMessage name={this.state.name} onChange={this.setMessage} />,
        <Send />
    ]
}

render(){
    return (
        <div>
           {this.stage[this.state.stage]}
           <button primary style={style.button} onClick={this.previousStage}> Previous </button>
                    <button primary style={style.button} onClick={this.nextStage}> Next </button>
                </div>

此组件根据用户注册的阶段呈现子项。我可以从父级的子节点接收回调(子节点设置父节点的状态),但是,当将state.name从parent传递给子节点作为prop时,子节点接收初始状态,这意味着名称为空字符串。 / p>

子组件:

class ContactMessage extends React.Component {
constructor(props){
    super(props);
    this.state ={
        message:'',
        name:''
    }
    this.handleChange=(event)=>{
        this.props.onChange(event.target.value);
        this.setState({message: event.target.value});
    }
}

componentWillReceiveProps(props){
    this.setState({name:props.name})
}


render(){

    return(
    <div>
                <h1>{this.state.name}</h1>
                <form onSubmit={this.handleSubmit}>
                    <label htmlFor='messageField'>
                    Message:
                    <input className='messageField' type="textfield" value={this.state.message}
                    onChange={this.handleChange} />
                    </label>
              </form>
            </div>

更新:我正在接收子组件中的初始道具,而不是来自父状态的更新道具。如何从父州获得新的和更新的道具?

3 个答案:

答案 0 :(得分:0)

正如我所看到的,在ContactPage中,您尝试将event(e)设置为state.name的值,而不是在this.setState({ name: e.target.value })方法中设置this. setName。 顺便说一句,您不必通过构造函数传递所有内容。 例如,

class MyComponent extends Component {
  state = {
    name: ''
  }

  handleChange = (e) => {
    this.setState({ [e.target.name]: e.target.value });
  }
  
  render() {
    return (
      <input name="name" value={this.state.name} onChange={this.handleChange} />
    );
  }
}

答案 1 :(得分:0)

尝试将stage数组提取到自己的方法中。类似的东西:

class ContactPage extends Component {
  constructor(props) {
    this.state = {
      stage: 0,
      name: 0
      // and so on
    }
  }
  getStage(index) {
    let stages = [
      <ContactName onChange={this.setName} />,
      <ContactInfo />,
      <ContactMessage name={this.state.name} onChange={this.setMessage} />,
      <Send />
    ];
    return stages[index];
  }
  render() {
    return (
      {this.getStage(this.state.stage)}
      <AllTheOtherStuff />
    )
  }
}

答案 2 :(得分:0)

我在这里注意到的三件事,可能是或不是您的问题。

第一:以状态的方式使用状态本质上是容易出错的。如果您同时显示{{1}和this.state.name中的name,并且从this.props中设置constructor,则只需跳过中间人并显示{{ 1}}。当状态值来自道具时,试图保持正确的状态确实很容易搞砸,因此最好直接使用道具。

第二:我相信您的问题是这里的1和2的混合,但是您在componentWillReceiveProps中声明了this.props.name变量,因此它只会使用它在stage。将constructor移到constructor中,它应该显示正确的状态信息。

第三:您使用componentWillReceiveProps的方式可能导致混乱。最好给变量起一个能准确描述变量含义的名称,而不会造成混淆。我将this.stage更改为render(),因为componentWillReceiveProps(props)更明确地说明了您正在处理哪些道具。