useEffect в React не обновляет компонент после обновления хранилища

Я не понимаю, почему React не обновляет мой объект. В другом компоненте через отправку обновляю состояние. В этом коде (в коде ниже) категории mapStateToProps меняются (в журнале консоли отображается еще одна категория). Но компонент не перерисовывается, хотя в компоненте in useEffect я использую props.categories. Событие console.log в элементе не запускается

const LeftSidebar = (props: any) => {
    console.log('not render after props.categories changed')
    useEffect(() => {
        props.dispatch(getCategories())
    }, [props.categories]);

    const addCategoryHandler = (categoryId: number) => {
        props.history.push('/category/create/' + categoryId)
    };

    return (
        <div className='left-sidebar'>
            <Logo/>
            <MenuSidebar categories={props.categories} onClickAddCategory={addCategoryHandler}/>
        </div>
    );
};

function mapStateToProps(state: State) {
    const categories = state.category && state.category.list;
    console.log('this categories changes, but LeftSidebar not changing')
    console.log(categories)
    return { categories };
}

export default connect(mapStateToProps)(LeftSidebar);

Я думал, что если я обновляю состояние, реагирую на компоненты обновления, зависящие от этого состояния. Как это должно работать? как это должно работать? Это может быть полезно, элемент, который добавляет категорию, не является родительским или дочерним, это сосед Мой редуктор

import {CATEGORIES_GET, CATEGORY_CREATE} from "../actions/types";

export default function (state={}, action: any) {
    switch (action.type) {
        case CATEGORIES_GET:
            return {...state, list: action.payload};
        case CATEGORY_CREATE:
            return {...state, list: action.payload};
        default: return state;
    }
}

Спасибо за решение проблемы. Вся проблема была в неизменяемых данных. Я использовал светильники, а не скопировал должным образом массив

import {CATEGORIES_GET, CATEGORY_CREATE} from "./types";
import {categoryMenuItems as items} from "../../fixtureData";
import {NewCategory} from "../../types";

let categoryMenuItems = items; // My mistake, I used not immutable value. Not use fixtures for state))
let id = 33;

export function getCategories() {
    return {
        type: CATEGORIES_GET,
        payload: categoryMenuItems
    }
}

export function createCategory(newCategory: NewCategory) {
    id++
    const category = {
        title: newCategory.name,
        id: id
    };

    // MISTAKE I use same array, not cloned like let clonedCategoryMenuItems = [...categoryMenuItems]
    categoryMenuItems.push(category);

    return {
        type: CATEGORY_CREATE,
        payload: categoryMenuItems
    }
}

Не используйте фикстуры для состояния, используйте настоящий api :)


person Billizzard    schedule 13.12.2019    source источник


Ответы (1)


Может быть, ваше состояние не является неизменным. В вашем редукторе используйте оператор распространения для добавления новых элементов

{
    list: [
       ...state.list,
       addedCategory
    ]
}

Вместо того

state.list.push(addedCategory)
person Alexander Vidaurre Arroyo    schedule 13.12.2019
comment
возможно проблема в том, что когда я добавляю категорию, я обновляю список категорий, как при получении категорий - person Billizzard; 13.12.2019
comment
Где добавить категорию в список категорий ?. Покажите этот код, пожалуйста - person Alexander Vidaurre Arroyo; 13.12.2019
comment
useEffect выполняет поверхностное сравнение своих зависимостей, поэтому, если вы добавляете новую категорию (с помощью метода push) в список, React интерпретирует это так, как если бы не было никаких изменений, потому что объект (список) остается тем же (с большим количеством элементов, но то же самое в конце дня) - person Alexander Vidaurre Arroyo; 13.12.2019
comment
Большое спасибо. Ты был прав. Я использовал не неизменные данные. Просто для теста я создал приборы с массивом категорий, а не клонировал его. Если я использую клонированный массив, все работает хорошо. Я опубликую действие с ошибкой и с комментарием, может быть кому-то полезно. Спасибо за упоминание неизменяемых данных - person Billizzard; 13.12.2019
comment
У меня такая проблема при использовании useSelector, useDispatch от react-redux - person cybercoder; 14.05.2020