在 componentWillReceiveProps 中反应设置状态 - 对于这个组件和父组件 - 反模式?
React setting state in componentWillReceiveProps - for this component and parent component - anti-pattern?
下面的代码在我的应用程序中运行良好。不过这似乎是一种反模式:
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
组件我的本地状态为 hideDiv
。
如果隐藏:
if (this.state.hideDiv)
显示它:
this.setState({
hideDiv: false,
}).
此外,如果我 收到一条新消息,我想增加 parent component
中的通知计数:
this.props.incrementNotificationCount()
此方法会导致通知 state
在 parent component
中发生更改。
问题:
我知道在 componentWillReceiveProps
中设置 local state
不会导致 rerender
。但是如果我在 componentWillReceiveProps
中设置 parent component
的 state
会发生什么?
这个代码是 "anti-pattern" 吗?
每当父组件重新渲染时, componentWillReceiveProps
in child 在调用子渲染函数之前被调用。在此函数中,如果您为 childComponent
调用 setState
,下一个状态将在 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>
下面的代码在我的应用程序中运行良好。不过这似乎是一种反模式:
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
组件我的本地状态为 hideDiv
。
如果隐藏:
if (this.state.hideDiv)
显示它:
this.setState({
hideDiv: false,
}).
此外,如果我 收到一条新消息,我想增加 parent component
中的通知计数:
this.props.incrementNotificationCount()
此方法会导致通知 state
在 parent component
中发生更改。
问题:
我知道在 componentWillReceiveProps
中设置 local state
不会导致 rerender
。但是如果我在 componentWillReceiveProps
中设置 parent component
的 state
会发生什么?
这个代码是 "anti-pattern" 吗?
每当父组件重新渲染时, componentWillReceiveProps
in child 在调用子渲染函数之前被调用。在此函数中,如果您为 childComponent
调用 setState
,下一个状态将在 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>