Всем привет. Пожалуйста, помогите разобраться с провайдером контекста.
Есть компонент Home, который находится в одной папке. Два других компонента Category и Sort находятся в другой папке. Логика фильтрации элементов находится в компоненте Home. Я хочу, чтобы все стэйты хранились в компоненте Home и, когда я выбираю определенную категорию продукта и тип сортировки, компоненты Category и Sort использовали состояния, находящиеся в Home. В свою очередь это позволит мне в компоненте Home в функции fetch прописать условия, согласно которым будут фильтроваться данные.
Из литературы я узнал, что поставщик контекста может поместить объект в контекст, но не может самостоятельно изменять значения объектов в контексте. Для этого нужно создать компонент с отслеживанием состояния, который будет отображать поставщика контекста.
Итак, что я сделал: в компонент Home создал компонент с отслеживанием состояния:
export const CategoryContext = createContext();
export function CategoryProvider({ children }) {
const [active, setActive] = useState(0);
return (
<CategoryContext.Provider value={{ active, setActive }}>
<Category />
</CategoryContext.Provider>
);
}
Значения value я взял из компонента Category, при этом useState в Category я удалил.
Компонент Category выглядит так:
import React from 'react';
import { useContext } from 'react';
import { useState } from 'react';
import { CategoryProvider, CategoryContext } from '../pages/Home';
function Category() {
const {active, setActive} = useContext(CategoryProvider);
const onClickCategory = (index) => {
setActive(index);
};
const pies = ['Все', 'Осетинские', 'Мясные', 'Закрытые', 'Сытные', 'Русские'];
return (
<div className="nav__category">
<ul className="nav__list">
{pies.map((value, i) => (
<li key={i} onClick={() => onClickCategory(i)} className={active === i ? 'active' : ''}>
{value}
</li>
))}
</ul>
</div>
);
}
export default Category;
Компонент Home выглядит так:
import React, { useEffect, useState } from 'react';
import Category from '../components/Category';
import Sort from '../components/Sort';
import PieBlock from '../components/PieBlock';
import Skeleton from '../components/Skeleton';
import { createContext } from 'react';
// Создаем провайдер контекста с отслеживанием состояния
export const CategoryContext = createContext();
export function CategoryProvider({ children }) {
const [active, setActive] = useState(0);
return (
<CategoryContext.Provider value={{ active, setActive }}>
<Category />
</CategoryContext.Provider>
);
}
const Home = () => {
const [items, setItems] = useState([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
fetch('https://636f5291f2ed5cb047daa480.mockapi.io/items')
.then((res) => res.json())
.then((arr) => {
setItems(arr);
setIsLoading(false);
});
}, []);
return (
<>
<nav className="container menu">
<Category />
<Sort />
</nav>
<h2 className="category__title">Все пироги</h2>
{/* Карточки */}
<div className="card__grid">
{isLoading
? [...new Array(6)].map((_, i) => <Skeleton key={i} />)
: items.map((obj, i) => <PieBlock {...obj} key={i} />)}
</div>
</>
);
};
export default Home;
При этом ничего не рендерится. Вероятно в компоненте Category я как-то неправильно пытаюсь использовать поставщик контекста, либо совсем не понял как применять контекст с отслеживанием состояния. Подскажите, в каком направлении мне копать, тяжело дается понимание контекста, но хочу разобраться. Буду рад любой помощи. Спасибо.