Реагировать, Redux, mapStateToProps и без повторного рендеринга, несмотря на изменения состояния - PullRequest
0 голосов
/ 10 июня 2018

У меня странная проблема с Redux и React.Состояние изменяется должным образом, и в mapStateToProps я также получаю правильное новое состояние, но после сопоставления компонент не будет перерисован.

Таким образом, компонент не перерисовывается:

import React, { Component } from 'react';
import { connect } from 'react-redux';

class ListItem extends Component {
    render() {
       return (<li>{this.props.item.text}</li>);
    }
}

const mapStateToProps = (state, ownProps) => {
    return {
        item: state.test.byID[ownProps.itemID]
    };
}

export default connect(mapStateToProps)(ListItem);

Но если я разделю предмет, компоненты переставят:

import React, { Component } from 'react';
import { connect } from 'react-redux';

class ListItem extends Component {
    render() {
       return(<li>{this.props.text}</li>);
    }
}

const mapStateToProps = (state, ownProps) => {
    return {
        id: state.test.byID[ownProps.itemID].id,
        text: state.test.byID[ownProps.itemID].text
    };
}

export default connect(mapStateToProps)(ListItem);

Понятия не имею почему.

Редуктор:

const startState = {
    byID: {
        'a1': {id: 'a1', text: 'test1'},
        'a2': {id: 'a2', text: 'test2'},
        'a3': {id: 'a3', text: 'test3'},
        'a4': {id: 'a4', text: 'test4'},
        'a5': {id: 'a5', text: 'test5'},
        'a6': {id: 'a6', text: 'test6'},
        'a7': {id: 'a7', text: 'test7'},
    },
    all: ['a1', 'a2','a3', 'a4', 'a5', 'a6', 'a7']
};


export default function reducer(state = startState, action) {
    switch (action.type) {
        case 'ADD_TEXT':
            const newState = {...state};
            newState.byID[action.id].text = action.text;
            return newState
        default:
            return state;
    }
}

Есть идеи?

1 Ответ

0 голосов
/ 10 июня 2018

Предполагается, что вы меняете поле text в одном из объектов byID массива.С вашим кодом:

newState.byID[action.id].text = action.text;

Вы изменяете свое состояние, поэтому у React могут возникнуть проблемы с распознаванием изменений, поскольку ссылка на объект в item prop не изменяется, только его свойства.Если сделана неглубокая проверка, она просто не будет повторно визуализироваться, так как «предположит», что объект вообще не изменяется.

Во втором сценарии вы возвращаете опору textэто строковый тип, поэтому не будет мелкой проверки, как с объектом, и равное сравнение === будет различать изменения и правильно перерисовывать компонент.

Для более подробной информации вы можете посмотреть на Неизменяемость в React .

Идея поддержания неизменности с помощью оператора распространения:

const newState = {...state};

Подходит для ссылки верхнего уровня, но не для вложенных дочерних объектов:

Распространение объекта делает поверхностную копию объекта.Клонируется только сам объект, а вложенные экземпляры не клонируются. Простое руководство по свойствам покоя / растекания объекта в JavaScript

Несмотря на то, что мутирующий объект кажется наиболее подверженной ошибкам частью в предоставленном вами коде, класс Component React может глубоко исследовать изменения объекта (PureComponent нет), и проблема может быть связана с другой проблемой.

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