useEffect не вызывается, когда в массив зависимостей передан контекст

Всем привет, есть компонент App:

const App = () => {
    const [ cards, setCards ] = useState(new Map());
    const [ theme, setTheme ] = useState({
        cards
    });

    // Запрашивает данные в виде Map и обновляет состояние cards
    useEffect(() => {
        (async () => {
            const cardsMap = await getCards('http://...');
            setCards(cardsMap);
        })();
    }, []);

    // когда обновляется cards, обновляет состояние контекста
    useEffect(() => {
        setTheme(Object.assign(theme, cards));
    }, [cards]);

    // Вызывется 2 раза: выводит пустой Map, затем выводит Map с данными
    console.log(theme);

    return (
        <div className="app">
            <Header />
            <ThemeContext.Provider value={{ theme, setTheme }}>
                <Main />
            </ThemeContext.Provider>
        </div>
    );
};

И есть компонент CardsBlock внутри провайдера:

const CardsBlock = () => {
    const { theme, setTheme } = useContext(ThemeContext);
    const [ currentCard, setCurrentCard ] = useState([]);

    useEffect(() => {
        const cardArray = theme.cards.get('cardsArray'); // undefined
        setCurrentCards(cardArray);
    }, [ theme ]);

    // Вызывается 1 раз, выводит пустой Map
    console.log(theme);

    return (
        <div className="cards-one">
            {/* Код, который зависит от контекста */}
        </div>
    );
};

В App console.log(theme) вызывается несколько раз: до и после того как данные загрузятся. console.log(theme) в CardsBlock вызывается только один раз, будто useEffect не подписан на его изменение. Из-за этого я не могу обновить состояние currentCard


Ответы (1 шт):

Автор решения: Sanya H

Не срабатывает, т.к. при изменении данных по ссылке, сама ссылка не изменяется. Вам нужно или пересоздавать объект (как написано в комментарии выше) или попробовать указать зависимостью не саму тему, а ее ссылочное свойство "карточки"

const CardsBlock = () => {
    const { theme, setTheme } = useContext(ThemeContext);
    const [ currentCard, setCurrentCard ] = useState([]);

    useEffect(() => {
        const cardArray = theme.cards.get('cardsArray'); // undefined
        setCurrentCards(cardArray);
    }, [ theme.cards ]);

    // Вызывается 1 раз, выводит пустой Map
    console.log(theme);

    return (
        <div className="cards-one">
            {/* Код, который зависит от контекста */}
        </div>
    );
};

→ Ссылка