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>
);
};