mapStateToProps获取新的道具但无法调用componentWillReceiveProps

问题描述 投票:1回答:2

我正在使用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。

javascript reactjs redux
2个回答
0
投票
constructor(props) {
    super();

    this.props = props;
    this.state = {
        headerBtn: []
    }
}

尝试将道具添加到超级

super(props);

0
投票

经过24小时的POC和调试后,尽管使用了扩展运算符,但我的reducer并没有返回一个新的对象:

let newState = {...state};
newState.name = ...

因此,我从互联网上读到的,以及Redux特定的doc解决方案是,如果状态发生可变变化,则不会调用mapStateToProps。这似乎不正确。在我的情况下或在任何状态变异的情况下,Redux都会调用mapStateToProps。它根本不会调用shouldComponentUpdate()。

扩散运算符的原因只是浅层复制对象。因此,如果对象中存在嵌套对象,则扩展运算符将保留对象的引用,因此,一旦更新内部对象,就会突变原始状态。要避免此类情况,请始终使用任何深度复制对象的工具。

_.cloneDeep(stateCopy, stateInitial) 

在我的情况下工作。

顺便说说,

console.log(newState === state) 

返回假,意味着状态没有变异,它确实是一个克隆状态。很奇怪。 :(

更新

避免使用扩展运算符。它不做深层复制。它仅适用于状态具有简单键值对的情况。对于嵌套在对象中的复杂对象,扩展运算符将严重失败。

© www.soinside.com 2019 - 2024. All rights reserved.