我正在使用React:16+和react-redux:6+
我连接了所有的动作和减速器。而且,在单击按钮时,我可以调用mapStateToProps(),但之后不会调用componentWillReceiveProps或shouldComponentUpdate。
这是我的代码:
class HeaderContainer extends React.Component {
constructor(props) {
super();
this.props = props;
this.state = {
headerBtn: []
}
}
componentWillReceiveProps(nextProps){
console.log(nextProps);
}
render() {
return (
<HeaderComponent className="flx-n-grow"
headerBtns={this.props.headerBtns}
selectExchange={this.props.selectExchange}/>
)
}
}
const mapStateToHeaderProps = (state) => {
console.log("received new props");
console.log(state);
console.log(state.HeaderReducer.headerBtns);
return {
headerBtns : state.HeaderReducer.headerBtns
}
}
const mapDispatchToHeaderProps = (dispatch) => {
return {
selectExchange: (exchanges, exchange) => {
dispatch(HeaderAction.selectExchange(exchanges, exchange));
}
}
}
export default connect(mapStateToHeaderProps, mapDispatchToHeaderProps)(HeaderContainer);
将调用mapStateToProps中的所有console.log,但永远不会调用componentWillReceiveProps或shouldComponentUpdate。
constructor(props) {
super();
this.props = props;
this.state = {
headerBtn: []
}
}
尝试将道具添加到超级
super(props);
经过24小时的POC和调试后,尽管使用了扩展运算符,但我的reducer并没有返回一个新的对象:
let newState = {...state};
newState.name = ...
因此,我从互联网上读到的,以及Redux特定的doc解决方案是,如果状态发生可变变化,则不会调用mapStateToProps。这似乎不正确。在我的情况下或在任何状态变异的情况下,Redux都会调用mapStateToProps。它根本不会调用shouldComponentUpdate()。
扩散运算符的原因只是浅层复制对象。因此,如果对象中存在嵌套对象,则扩展运算符将保留对象的引用,因此,一旦更新内部对象,就会突变原始状态。要避免此类情况,请始终使用任何深度复制对象的工具。
_.cloneDeep(stateCopy, stateInitial)
在我的情况下工作。
顺便说说,
console.log(newState === state)
返回假,意味着状态没有变异,它确实是一个克隆状态。很奇怪。 :(
避免使用扩展运算符。它不做深层复制。它仅适用于状态具有简单键值对的情况。对于嵌套在对象中的复杂对象,扩展运算符将严重失败。