Только сопоставление вложенного объекта состояния с реквизитом не будет обновлять компонент - PullRequest
0 голосов
/ 23 апреля 2019

Я использую mapStateToProps, чтобы получить вложенный объект от объекта по идентификатору. Проблема в том, что реквизиты не обновляются, и componentDidUpdate не будет срабатывать при изменении состояния хранилища с избыточностью.

Вот мои редукторы:

export const programmReducers = (state = initialState, action) => {
    let programms = state.programms;

    switch (action.type) {
        case actionTypes.FETCH_CATEGORIES:
            return Object.assign({}, state, {
                categories: action.payload
            })
        case actionTypes.FETCH_PROGRAMM:
            programms[action.payload.id] = action.payload;
            console.log(programms);
            return {
                ...state,
                programms: Object.assign({}, programms)
            }
        case actionTypes.FETCH_PROGRAMM_COMPONENTS:
            programms[action.programmId].components = action.payload;
            console.log('Added Components')
            return {
                ...state,
                programms: Object.assign({}, programms)
            }
        case actionTypes.FETCH_PROGRAMM_SECTIONS:
            programms[action.programmId].sections = action.payload;
            console.log('Added Sections')
            return {
                ...state,
                programms: Object.assign({}, programms)
            }
        default:
            return state
    }
}

Вот мои компоненты:

class ProgrammPage extends Component {

    static async getInitialProps({ store, query: {id} }) {
        if (!store.getState().programm.programms[id]) {
            console.log('Programm not! found');
            await store.dispatch(loadProgramm(id));
            await store.dispatch(loadProgrammComponents(id));
        } else {
            console.log('Programm found')
        }

        return {
            programmId: id
        }
    }

    constructor(props) {
        super(props);

        if (this.props.user) {
            console.log('Loading init!');
            this.props.loadProgrammComponents(this.props.programmId)
            this.props.loadProgrammSections(this.props.programmId);
        }
    }

    componentDidUpdate(prevProps) {
        console.log('Update')
        if (!prevProps.user && this.props.user) {
            console.log('Loading update');
            this.props.loadProgrammComponents(this.props.programmId);
            this.props.loadProgrammSections(this.props.programmId);
        }
    }

    render() {
        return (
            <div>
                <h1>Programm</h1>
                <h2>{this.props.programm.name}</h2>
                <h2>{this.props.programm.id}</h2>
                <h3>Components: {this.props.programm.components ? this.props.programm.components.length : 'None'}</h3>
                <h3>Sections: {this.props.programm.sections ? this.props.programm.sections.length : 'None'}</h3>
                <br></br>
                <h1>User: { this.props.user ? this.props.user.uid : 'None'}</h1>
                <button onClick={() => this.props.loadProgramm('ProgrammLevel2')}>Load Programm</button>
                <button onClick={() => this.props.loadProgrammComponents(this.props.programmId)}>Load Components</button>
            </div>
        )
    }
}

function mapStateToProps(state, ownProps) {
    return {
        programm: state.programm.programms[ownProps.programmId],
        // programms: state.programm.programms <--- Fixed the problem
        user: state.auth.user
    }
}

const mapDispatchToProps = dispatch => bindActionCreators({
    loadProgramm,
    loadProgrammComponents,
    loadProgrammSections
}, dispatch)

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(ProgrammPage)

Когда редуктор для FETCH_PROGRAMM_COMPONENTS или FETCH_PROGRAMM_SECTIONS изменяет состояние редукции, componentDidUpdate не вызывается и компонент не отображает изменения.

Проблема, похоже, связана с методом mapStateToProps, потому что, когда я добавляю programms: state.programm.programms, все работает нормально. Однако мне не нужен весь объект программ.

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

1 Ответ

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

Ваша проблема в programmReducers, ваш компонент не рендерится, потому что вы не меняете состояние.

После изменения mapStateToProps вам необходимо внести изменения в ваш компонент.

Следующий код, вероятно, нарушается, когда вы изменяете programms: state.programm.programms на programm: state.programm.programms[ownProps.programmId]

export const programmReducers = (state = initialState, action) => {
    let programms = state.programms;
    ...
}

Так что я предполагаю, что ваши редукторы не выполняют то, что вы хотели.

...