A
A
Andrey Novikov2020-10-22 22:02:56
React
Andrey Novikov, 2020-10-22 22:02:56

Why does reducer not see array changes?

Good evening! React and react-redux question. I have a store with comments and I want to add another comment to it. It is added, but the component that displays the comments is not re-rendered. Through experience, I found out that the reducer passes a new array with comments ( data ) to the store, but does not cause the component to re-render. If a certain flag is added to the object to the comments array and its state is changed each time, then everything works fine. But it's still a crutch, how can you do without it?

import * as Comments from '../constants/commentsConstants';

export function commentsReducer(state = {data: [], marker: false}, action) {
    switch (action.type) {
        case Comments.ADD_COMMENT: {
            let newData = state.data;
            newData.push({
                postId: action.payload.postId,
                body: action.payload.body,
                name: action.payload.name,
                id: state.data[state.data.length - 1].id + 1
            });
            
            state = {...state, is_fetching: false, data: newData, marker: !state.marker};
            // state = {...state, is_fetching: false, data: newData}; - Так не работает
            break;
        }
    }

    return state;
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
i1yas, 2020-10-22
@Andreeyyy

Reducer Documentation https://redux.js.org/basics/reducers
Specifically:

It's very important that the reducer stays pure. Things you should never do inside a reducer:
Mutate its arguments;
Perform side effects like API calls and routing transitions;
Call non-pure functions, eg Date.now() or Math.random().

You mutate the incoming state
. You need to repair something like this:
export function commentsReducer(state = {data: [], marker: false}, action) {
    switch (action.type) {
        case Comments.ADD_COMMENT: {
            let newData = state.data.slice(); // копируем массив
            newData.push({
                postId: action.payload.postId,
                body: action.payload.body,
                name: action.payload.name,
                id: state.data[state.data.length - 1].id + 1
            });
            
            // никакого state = ...
            return {...state, is_fetching: false, data: newData};
        }
    }
    return state;
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question