假设我们具有以下设置,带有两个孩子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
大多数时候都可以正常工作。