简体   繁体   English

反应:将作为道具传递的状态分配给组件作为变量阻止更新?

[英]React: Assigning State Passed as Prop to Component as Variable Prevents Update?

Suppose we have the following setup with a parent component with two children C1 and C2: 假设我们有一个带有两个子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

Here it is in code and codepen : 它在代码和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'));

Notice that in C2's constructor, we have a reference to this.props.data . 注意,在C2的构造函数中,我们引用了this.props.data If we set that variable as a class attribute like this.data = this.props.data React fails to update C1 even after we click the update button and Example's this.state.data has been changed. 如果我们将该变量设置为类似于this.data = this.props.data的类属性,即使单击更新按钮并且示例的this.state.data已更改,React仍无法更新C1。 I have commented out the line that works, which references this.props.data directly. 我已经注释掉了可以直接引用this.props.data的行。

My first idea is that this must be illegal syntax in React. 我的第一个想法是在React中这必须是非法语法。 However, further testing with C1 showed that if the props passed in is a function and not state, there is no problem (see the code under C1's update function to confirm what I am talking about). 但是,使用C1进行的进一步测试表明,如果传入的props是一个函数而不是状态,则没有问题(请参阅C1的update函数下的代码以确认我在说什么)。

Why does this not work for state passed in as props but works for functions passed in as props? 为什么这对于作为props传入的状态不起作用,但对于作为props传入的函数却起作用? I would assume Example sees that C1 has changed data state and as a result of this, call a re-rendering of C2 which uses this.data to figure out what to render next. 我假设Example看到C1更改了data状态,并因此导致调用C2的重新渲染,该渲染使用this.data找出接下来要渲染的内容。

Because the constructor only gets called once and not every time it gets new state or props so your class variables references the props passed initially and not the new ones because it doesn't rerun the constructor again. 因为constructor只会被调用一次,而不是每次都获得新状态或道具,所以您的类变量引用的是最初传递的道具,而不是新的道具,因为它不会再次运行构造函数。 See constructor 构造函数

The constructor for a React component is called before it is mounted React组件的构造函数在挂载之前被调用

So once it's mounted, it doesn't get called again. 因此,一旦安装,就不会再被调用。 The functions on the other hand, especially pure functions, will work fine because you didn't modify the function itself or any values within it. 另一方面,这些函数(尤其是纯函数)可以正常工作,因为您没有修改函数本身或其中的任何值。

If you want to update the class variables based on props change you might want to check shouldComponentUpdate or componentWillReceiveProps 如果您想根据道具更改来更新类变量,则可能需要检查shouldComponentUpdatecomponentWillReceiveProps

So example in your C2 component, to fix it use this: 因此,在您的C2组件中使用以下示例进行修复:

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

But I think it's redundant doing that, this.props works fine most of the time. 但是我认为这样做是多余的, this.props大多数情况下this.props正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM