我将来自Parent组件的道具传递给Child的状态,但它们不同步。
我尝试了什么:
我正在使用React 16和es6语法
class Parent extends React.Component {
state = {
isHidden: false
}
render() {
console.log('PROPS from PARENT', this.state.isHidden)
return <div>
<Child isOpen={this.state.isHidden} />
<button onClick={this.toggleModal}>Toggle Modal</button>
</div>
}
toggleModal = () => this.setState(state => ({isHidden: !state.isHidden}))
}
class Child extends React.Component {
state = {
isHidden: this.props.isOpen
}
render() {
console.log('STATE of CHILD:',this.state.isHidden)
return <p hidden={this.state.isHidden}>Hidden:{this.state.isHidden}</p>
}
}
ReactDOM.render(<Parent/>, document.getElementById('app'));
这里有一个codepen PEN - 注意应该根据状态隐藏redered元素(state依赖于来自parent的props)
答案 0 :(得分:2)
如果从孩子那里删除状态定义(不需要),并且只使用从父母传递的道具,我相信孩子的行为是有意义的。
如果你想在子节点中使用state,那么构造函数设置是不够的,你需要在props更改时设置子状态。
Console.log是异步的,所以你不能在这里依赖它。
答案 1 :(得分:2)
使用componentWillReceiveProps
在props
发生变化时调用。
class Child extends React.Component {
state = {
isHidden: this.props.isOpen
}
componentWillReceiveProps(props) {
if (props.isOpen != this.state.isHidden)
this.setState({
isHidden: props.isOpen
})
}
render() {
console.log('STATE of CHILD:', this.state.isHidden)
return <p hidden = {
this.state.isHidden
} > Hidden: {
this.state.isHidden
} < /p>
}
}
答案 2 :(得分:1)
由于组件对构造函数中的状态更改一无所知,因此您的子状态不会随着prop更改而改变。当你依靠道具建造当地的州时,这是一个常见的陷阱。您可以使用@Nishant Dixit的答案中所示的componentWillReceiveProps。但是,从React 16.3开始,我们为此获得了getDerivedStateFromProps函数(lifecylce方法)。
static getDerivedStateFromProps( props, state) {
if( props.isOpen === state.isHidden) {
return null;
}
return {
isHidden: props.isOpen,
}
}
在这里,我们正在比较我们的道具和状态,如果有变化,我们将返回所需状态。无需使用this.setState。
相关API更改博客文章,包括异步呈现: https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html
答案 3 :(得分:1)
虽然其他答案会使代码有效,但实际上有更优雅的解决方案:)
您的子组件不需要任何状态,因为状态由Parent管理(它管理isHidden
属性并将其传递给子级)。所以子组件应该只关心道具。
尝试编写这样的组件,我相信它应该有效:
class Child extends React.Component {
render() {
return <p hidden={this.props.isHidden}>Hidden:{this.props.isHidden}</p>
}
}
在React团队工作的Dan Abramov在Twitter上发布了关于这个问题的推文 - 基本上说你应该认真考虑是否可以在组件中使用状态之前使用道具 https://twitter.com/dan_abramov/status/979520339968516097?lang=en