Всем привет.
Создал контекст в файле Context.js
import { createContext, useReducer } from 'react';
import { reducer } from './reducer';
import {
CLOSE_ALERT,
REMOVE_FROM_BASKET,
SET_GOODS,
SET_IS_BASKET_SHOW,
SET_LOADING,
UPDATE_CART,
} from './../reducer_vars/shop_vars';
export const ShopContext = createContext();
const initialState = {
goods: [],
loading: false,
orders: [],
isBasketShow: false,
error: null,
toast: '',
};
export const ContextProvider = ({ children }) => {
const [value, dispatch] = useReducer(reducer, initialState);
value.closeAlert = () => {
dispatch({ type: CLOSE_ALERT });
};
value.removeBasketItem = (id) => {
dispatch({ type: REMOVE_FROM_BASKET, payload: id });
};
value.updateCart = (item) => {
dispatch({ type: UPDATE_CART, payload: item });
};
value.setGoods = (items) => {
dispatch({ type: SET_GOODS, payload: items });
};
value.setLoading = (data) => {
dispatch({ type: SET_LOADING, payload: data });
};
value.setIsBasketShow = (data) => {
dispatch({ type: SET_IS_BASKET_SHOW, payload: data });
};
return (
<ShopContext.Provider value={value}>{children}</ShopContext.Provider>
);
};
В файле root.jsx находится точка входа в приложении
import { NavLink, Outlet } from 'react-router-dom';
// import { ContextProvider } from '../context/Context';
export default function Root() {
return (
<>
<nav className="header">
<div className="nav-wrapper">
<ul className="left hide-on-med-and-down menu">
<li>
<NavLink to={'/'}>Home</NavLink>
</li>
<li>
<NavLink to={'/hooks'}>Hooks</NavLink>
</li>
<li>
<NavLink to={'/counter'}>Counter</NavLink>
</li>
<li>
<NavLink to={'/reducer'}>Use Reducer</NavLink>
</li>
<li>
<NavLink to={'/goods'}>Goods</NavLink>
</li>
<li>
<NavLink to={'/todos'}>Todos</NavLink>
</li>
</ul>
</div>
</nav>
<div className="main">
<Outlet />
</div>
<footer className="page-footer">
<div className="footer-copyright">
<div className="container">
© 2022 Copyright Text
<a className="grey-text text-lighten-4 right" href="#!">
More Links
</a>
</div>
</div>
</footer>
</>
);
}
Также сдоздал layout GoodsLayout.jsx
import React from 'react';
import { ContextProvider } from '../context/Context';
export default function GoodsLayout({ children }) {
return (
<ContextProvider>
<div>{children}</div>
</ContextProvider>
);
}
Ну и страница GoodsPage.jsx
import { useContext, useEffect, useState } from 'react';
import GoodsLayout from '../layouts/GoodsLayout';
import Basket from '../components/goods/Basket';
import Cart from '../components/goods/Cart';
import GoodsList from '../components/goods/GoodsList';
import Preloader from '../components/UI/Preloader';
import Toast from '../components/UI/Toast';
import { APP_KEY, APP_URL } from '../config';
import { ShopContext } from '../context/Context';
const GoodsPage = () => {
const {
toast,
goods,
setGoods,
loading,
setLoading,
setIsBasketShow,
isBasketShow,
} = useContext(ShopContext);
const [error, setError] = useState(null);
function toggleBasket() {
setIsBasketShow(!isBasketShow);
}
useEffect(function getGoods() {
setLoading(true);
fetch(APP_URL, {
headers: {
Authorization: APP_KEY,
},
})
.then((response) => response.json())
.then((data) => {
setGoods(data.shop);
setTimeout(() => {
setLoading(false);
}, 1000);
})
.catch((error) => {
setError('Access token is invalid');
console.log(error, 'error');
setLoading(false);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<GoodsLayout>
<div className="mt4">
<div className="container">
<h2>Goods</h2>
{loading ? (
<Preloader />
) : error ? (
<h3 className="center red-text">{error}</h3>
) : (
<GoodsList goods={goods} />
)}
<Cart toggleBasket={toggleBasket} />
</div>
{isBasketShow && <Basket />}
{toast !== '' && <Toast message={toast} />}
</div>
</GoodsLayout>
);
};
export default GoodsPage;
Если делать по правилам из документации, то есть, в файле root.jsx оборачивать в
Проблема в том, что у меня будут множество страниц, и хочется использовать контекст только на этой.
Сам контекст не может быть использован на самой странице, по-этому и создал layout, только с ним не работает страница GoodsPage.jsx
Uncaught TypeError: Cannot destructure property 'toast' of '(0 , react__WEBPACK_IMPORTED_MODULE_0__.useContext)(...)' as it is undefined.
at GoodsPage (GoodsPage.jsx:13:1)
По-ходу, что-то не так делаю?