以下代码在我的应用中运行良好。这似乎是一种反模式:
componentWillReceiveProps(nextProps) {
if (nextProps.conversation.length > this.props.conversation.length){
if (this.state.hideDiv) {
this.setState({
hideDiv: false,
});
}
this.props.incrementNotificationCount();
}
}
解释:
componentWillReceiveProps
检查nextProps
会话数组是否大于this.props
覆盖数组。含义:我收到了一条新的对话信息。
如果我 收到新邮件,我只想在隐藏时显示div ,在this
组件中我有本地状态{ {1}}。
如果隐藏:
hideDiv
显示:
if (this.state.hideDiv)
此外,如果我 收到新邮件,我想增加this.setState({
hideDiv: false,
}).
中的通知计数:
parent component
此方法会在this.props.incrementNotificationCount()
中更改通知state
。
问题:
我知道在parent component
中设置本地 state
不会导致componentWillReceiveProps
。但是如果我在rerender
中设置state
的{{1}}会怎样?
这段代码是“反模式”吗?
答案 0 :(得分:1)
每当父组件重新呈现时,在调用子呈现函数之前调用child中的componentWillReceiveProps
。在此函数中,如果为setState
调用childComponent
,则在componentWillUpdate
函数中更新下一个状态,然后由子项中的渲染接收。
同样,当您调用更新父状态的componentWillReceiveProps
中的父函数时,父项为rerendered
,因此子项将再次重新呈现。
查看演示相同行为的示例代码段
class Parent extends React.Component {
state = {
childState: 1,
mystate: 2,
}
changeState = () => {
console.log('change state in parent called');
this.setState((prevState) => ({
mystate: prevState.mystate + 1
}))
}
componentWillUpdate(nextProps, nextState) {
console.log('cwu parent', nextState);
}
changeChildState = () => {
console.log('change child state called');
this.setState((prevState) => ({
childState: prevState.childState + 1
})
)
}
render() {
console.log('Parent rerender called');
return (
<div>
<div> Parent {this.state.mystate}</div>
<button onClick={() => this.changeChildState()}>Click</button>
<MyComponent val={this.state.childState} changeState={this.changeState}/>
</div>
)
}
}
class MyComponent extends React.Component {
state = {
someChildState: 1
}
componentWillReceiveProps(nextProps) {
if(nextProps.val !== this.props.val) {
console.log('child cwrp called');
this.setState((prevState) => ({someChildState: prevState.someChildState + 1}));
this.props.changeState();
}
}
componentWillUpdate(nextProps, nextState) {
console.log(nextState)
}
render() {
console.log('child render called')
return <div > {this.props.val} {this.state.someChildState} </div>
}
}
ReactDOM.render(<Parent/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>