mapStateToProps получает новые реквизиты, но не может вызвать componentWillReceiveProps - PullRequest
1 голос
/ 19 апреля 2019

Я использую Реакт: 16+ и Реакция-Избыток: 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);

Все console.log внутри mapStateToProps вызывается, но componentWillReceiveProps или shouldComponentUpdate никогда не вызывается.

Ответы [ 2 ]

0 голосов
/ 20 апреля 2019

После 24 часов POC и отладки выясняется, что мой редуктор не возвращал новый объект, несмотря на использование оператора распространения:

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

Итак, что я читаю из Интернета, и Redux, в частности, устраняет неполадки с документом, так это то, что если состояние изменяется изменчиво, то mapStateToProps не будет вызываться. Это кажется неверным. В моем случае или в любом случае изменения состояния Redux вызывает mapStateToProps. Он просто не будет вызывать shouldComponentUpdate ().

Причина, по которой распространяемый оператор только копирует объект. Таким образом, если в объекте есть вложенные объекты, оператор распространения будет сохранять ссылку на объект и, следовательно, после обновления внутреннего объекта исходное состояние будет изменено. Чтобы избежать таких сценариев, всегда используйте любой инструмент для глубокого копирования объекта.

_.cloneDeep(stateCopy, stateInitial) 

работал в моем случае.

Кстати,

console.log(newState === state) 

вернул false, что означает, что состояние не было мутированным, это действительно было клонированное состояние. Очень странно. (

Обновление

Не используйте оператор распространения. Это не делает глубокую копию. Это хорошо только для случаев, когда у государства есть простая пара ключ-значение. Для сложных объектов, вложенных в объекты, оператор распространения будет плохо работать.

0 голосов
/ 19 апреля 2019
constructor(props) {
    super();

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

попробуйте добавить реквизит в супер

super(props);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...