反应:将传递给组件的状态分配给组件,因为变量阻止了更新



假设我们具有以下设置,带有两个孩子C1和C2的父组件:

Example: container for C1 and C2, with a state called data
    -C1: input, updates state in Example through handler passed as propdisplay, shows state from Example
    -C2: display, shows state from Example

在这里,它在代码中,codepen:

class Example extends React.Component {
  constructor (props) {
    super(props)
    this.state = { data: 'test' }
  }
  onUpdate (data) { this.setState({ data }) }
  render () {
    return (
      <div>
        <C1 onUpdate={this.onUpdate.bind(this)}/>
        <C2 data={this.state.data}/>
      </div>
    )
  }
}
class C1 extends React.Component {
    constructor(props) {
      super(props);
      this.onUpdate = this.props.onUpdate;
    }
    render () {
      return (
        <div>
          <input type='text' ref='myInput'/>
          <input type='button' onClick={this.update.bind(this)} value='Update C2'/>
        </div>
      )
    }
    update () {
      //this.props.onUpdate(this.refs.myInput.getDOMNode().value);
      this.onUpdate(this.refs.myInput.getDOMNode().value);
    }
}
class C2 extends React.Component {
    constructor(props) {
      super(props);
      this.data = this.props.data;
    }
    render () {
      return <div>{this.props.data}</div>
      //return <div>{this.data}</div>
    }
}
/*
 * Render the above component into the div#app
 */
React.render(<Example />, document.getElementById('app'));

请注意,在C2的构造函数中,我们对this.props.data有一个引用。如果我们将该变量设置为类属性(例如this.data = this.props.data React),即使我们单击"更新"按钮和示例为this.state.data已更改,也无法更新C1。我已经评论了有效的行,它直接引用了this.props.data。

我的第一个想法是,这必须是反应中的非法语法。但是,使用C1进行进一步的测试表明,如果通过的道具是一个函数而不是状态,则没有问题(请参阅C1 update功能下的代码以确认我在说什么)。

为什么这不适合通过作为道具传递的状态,而是适用于通过作为道具传递的功能?我假设例如看到C1改变了data状态,因此,请调用C2的重新渲染,该订阅使用this.data来弄清楚下一步呈现。

,因为constructor仅被调用一次,而不是每次获得新状态或道具,因此您的类变量引用了最初通过的道具而不是新的,因为它不会重新运行构造函数再次。请参阅构造函数

在安装后,调用了反应组件的构造函数

因此,一旦安装,它就不会再次被调用。另一方面,功能,尤其是纯函数,可以正常工作,因为您没有修改功能本身或其中的任何值。

如果您想根据道具更改类变量,则可能需要检查shows shipcomponentupdate或componentWillReceiveProps

因此,您的C2组件中的示例要修复此操作:

componentWillReceiveProps(nextProps) {
  this.data = this.nextProps.data
}

但我认为这样做是多余的,this.props大多数时候都可以正常工作。

相关内容

最新更新