反应状态已更改,无法重新呈现子级

时间:2019-07-31 16:54:36

标签: reactjs

我想将两个子字段绑定在一起。 我在父类中创建了更改处理程序,并在子项的props中传递了状态值。 每当我在文本字段中键入内容时,父状态和子道具都会更新,我可以在react dev工具中看到它,但是子状态不会得到反映。

下面是我的代码

class Parent extends React.Component{

    constructor(props){
        super(props);
        this.state = {value: "test"};
        this.changeHandler = this.changeHandler.bind(this);
    }

    changeHandler(value){
        this.setState({value: value});
    }

    render(){
        return (
                <div>
                    <Child value={this.state.value} change={this.changeHandler}/>
                    <Child value={this.state.value} change={this.changeHandler}/>
                </div>
                );
    }
}

class Child extends React.Component{

    constructor(props){
        super(props);
        this.changeHandler = this.changeHandler.bind(this);
        this.state = {value: this.props.value};
    }

    changeHandler(e){
        this.setState({value:e.target.value});
        this.props.change(e.target.value);
    }

    render(){
        return (
                <input type="text" value={this.state.value} onChange={this.changeHandler} />
                );
    }

}

ReactDOM.render(<Parent/>, document.getElementById('root'));

3 个答案:

答案 0 :(得分:5)

这是因为您正在使用

class Child extends React.Component{

    constructor(props){
        super(props);
        this.changeHandler = this.changeHandler.bind(this);
        // ...............  ?
        this.state = {value: this.props.value};
    }
    // ... 
}

在组件安装阶段,您的内部this.state.value仅设置为“一次”。
这意味着,每当Parent -> this.state.value发生更改并导致Child组件重新呈现时,this.state = {value: this.props.value};都不会再次被调用

与其在子组件中使用状态,不如在您的this.props.value字段上直接使用<Input />

<input type="text" value={this.props.value} onChange={this.changeHandler} />

流程如此,某人在Child.input中键入内容,告诉Parent更新状态,然后将更改回传到您的Child -> this.props.value

然后您通过调用传递的this.props.changeHandler来通知Parent。

因此,最终的Child组件如下所示。

class Child extends React.Component{
    constructor(props){
        super(props);
        this.changeHandler = this.changeHandler.bind(this);
    }

    changeHandler(e){
        this.props.changeHandler({value:e.target.value});
    }

    render(){
        return (
          <input type="text" value={this.props.value} onChange={this.changeHandler} />
        );
    }

}

如果使用ES6“ arrow functions”语法,则可以使其更小,而无需使用this.changeHandler = this.changeHandler.bind(this)
这是因为箭头函数不会创建自己的this,而是使用调用上下文的this

class Child extends React.Component{
    constructor(props){
        super(props);
    }

    changeHandler = (e) => {
        this.props.changeHandler({value:e.target.value});
    }

    render(){
        return (
          <input type="text" value={this.props.value} onChange={this.changeHandler} />
        );
    }

}

或者您可以直接从onChange调用它。

class Child extends React.Component {
  render() {
    return (
      <input
        type="text"
        value={this.props.value}
        onChange={this.props.changeHandler}
      />
    );
  }
}

我们可以进一步将其转换为Function Component(不是“功能性”组件,因为它与功能性编程无关)

function Child({ value, changeHandler}) {
  return <input type="text" value={value} onChange={changeHandler} />
}

// or
const Child = ({value, changeHandler}) => 
  <input type="text" value={value} onChange={changeHandler} />

当您使用const Child = ...时,请确保已将其声明为Parent之前。但是,当您使用function Child时,由于JavaScript提升的工作原理,它可能会出现在Parent之前或之后。

最后,无需更改Parent

答案 1 :(得分:2)

您需要实现componentDidUpdate

class Parent extends React.Component{

constructor(props){
    super(props);
    this.state = {value: "test"};
    this.changeHandler = this.changeHandler.bind(this);
}

changeHandler(value){
    this.setState({value: value});
}

render() {
    return (
            <div>
                <Child value={this.state.value} change={this.changeHandler}/>
                <Child value={this.state.value} change={this.changeHandler}/>
            </div>
            );
    }
 }

class Child extends React.Component{

constructor(props){
    super(props);
    this.changeHandler = this.changeHandler.bind(this);
    this.state = {value: this.props.value};
}


changeHandler(e){
    this.setState({value:e.target.value});
    this.props.change(e.target.value);
}

componentDidUpdate(prevProps) {
  if(prevProps.value !== this.props.value) {
      this.setState({value: this.props.value});
  }
}

render(){
    return (
            <input type="text" value={this.state.value} onChange={this.changeHandler} />
            );
}

}
ReactDOM.render(<Parent/>, document.getElementById('root'));

答案 2 :(得分:0)

每个子组件都有其自己的独立状态。如果要在两者之间共享该值,则可以将其从子级的状态中删除,而仅在子级中使用this.props.value。然后,值仅在父级中是可变的。