使孩子的输入取决于父输入值

时间:2019-03-07 12:08:00

标签: reactjs

我的目标是

  1. 使用父母各自的值初始化孩子的状态。为此,我使用以下代码在构造函数中设置子代的状态值:
  2. 尽快重置父母的孩子的价值
  3. 保持改变孩子价值的能力

为了实现第二个目标,我通过以下方式使用getDerivedStateFromProps https://codepen.io/jedgar-nawasardqn/pen/VRpWrZ?editors=1011

class Parent extends React.Component { 
    constructor(props) {
        super(props)
        this.state = {
          value: "default valu"
        }
    }
    onChange = (value) => {
         this.setState({
              value: value
         })
    }

    render() {

      return (
          <div>
              <form>
                 <label>Parent: </label>
                 <input
                 value={this.state.value}
                 onChange={(e) => this.onChange(e.target.value)}/>
              </form>
              <Child
                 value={this.state.value}/>
          </div>);
      }
}

class Child extends React.Component {

  constructor(props) {
        super(props)
        this.state = {
          value: this.props.value
        }
    }
   static getDerivedStateFromProps(nextProps, prevState) {
     console.log('nextProps', nextProps)   
     return {
            value: nextProps.value
        }
    }
  onChange = (value) => {
         console.log('CHild changed')
         this.setState({
              value: value
         })
    } 
  render() {
       return (
         <div>
           <label>Child: </label>
           <input
                value={this.state.value}
                onChange={(e) => this.onChange(e.target.value)}/>
         </div>)
   }
}

React.render(<Parent/>, document.getElementById('app'));

...但是由于某种原因,我无法使其正常运行。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

假设我了解您的目标,即希望在父项更改时让父项输入控制子项输入,但允许子项输入自身更改而不影响父项:

问题在于getDerivedStateFromProps无论如何都被调用,因此当您从Child的输入更改状态时,getDerivedStateFromProps立即将其恢复为Parent的值。您应该使用componentDidUpdate并区分道具,而不要使用getDerivedStateFromProps并仅在父级状态实际更改时才更新子级以匹配父级。

我根据您的小提琴制作了一个代码沙箱,以证明这一点:https://codesandbox.io/s/m5qj6qq769?fontsize=14

答案 1 :(得分:0)

首先,即使与您的问题无关,我建议您也不要在render()方法内使用箭头功能,因此,您应该只编写{{1} }。原因是将创建箭头函数,然后在每个onChange={(e) => this.onChange(e.target.value)} />处将其丢弃:如果渲染器和箭头函数很少,这没什么大不了的,但是最好避免浪费计算能力:)

现在,关于您的问题!老实说,似乎onChange={this.onChange} />组件只需要显示值,因此,将值从render()组件“复制”到Child组件并没有真正的作用:您可以保留您在Parent组件中的值,然后在ChildParent组件中引用该值。 为此,您还需要将处理函数传递给Parent组件。 让我们看看小提琴吧!

Child
Child
class Child extends React.Component {
    constructor(props) {
        super(props);
    }
    
    render() {
        return (
            <div>
                <label>Child: </label>
                <input
                    value={this.props.value}
                    onChange={this.props.handleChange}/>
            </div>
        );
    }
}

class Parent extends React.Component {
    constructor(props) {
        super(props);
        
        this.state = {value: "Default Value"};
    }
    
    handleChange = (e) => {
        this.setState({value: e.target.value});
    }
    
    render() {
        return (
            <div>
                <form>
                    <label>Parent: </label>
                        <input
                            value={this.state.value}
                            onChange={this.handleChange} />
                </form>
                <Child
                    value={this.state.value}
                    handleChange={this.handleChange} />
          </div>
        );
    }
}

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