Сегодня мы узнаем, как использовать React Context API для обмена значениями в нашем приложении и как использовать хук useReducer для управления состояниями в нашем проекте.
В качестве примера в этой статье я буду использовать проект электронной коммерции. Использование React’s context API и useReducer для обмена состояниями в нашем приложении и для возможности изменять эти состояния в нашем приложении.
Начнем с React Context API,
Для начала мы создадим контекст и присвоим его переменной ProductContext. Это создаст объект контекста, и каждый объект контекста поставляется с компонентом Provider React, который позволяет потребляющим компонентам подписываться на изменения контекста.
//product_context.js
const ProductContext = React.createContext()
Но что такое “потребляющие компоненты”? Потребляющие компоненты – это компоненты, которые обернуты в Provider React Component из контекстного объекта. В данном случае мы создаем собственный React Component, который возвращает этот Provider.
//product_context.js
const ProductContext = React.createContext()
export const ProductsProvider = ({ children }) => {
return (
<ProductContext.Provider value={}>
{children}
</ProductContext.Provider>
);
};
Любой компонент, являющийся дочерним по отношению к нашему компоненту ProductsProvider, будет являться потребляющим компонентом нашего контекста и иметь доступ к значениям, которые предоставляет наш контекст.
Что же это за “значения, которые предоставляет наш контекст”, ну, это зависит от нас, чтобы предоставить любые функции или переменные, которые мы хотим, чтобы предоставлял наш контекст. В нашем случае мы хотим передать функцию fetchProducts, как показано ниже.
//product_context.js
export const ProductsProvider = ({ children }) => {
const fetchProducts = async () => {
let response = {};
try {
response = await axios.get(url);
let products = response.data;
} catch (error) {
console.log({ error });
}
};
return (
<ProductContext.Provider value={{fetchProducts}}>
{children}
</ProductContext.Provider>
);
};
В компоненте ProductsProvider я создал функцию fetchProducts, которая предназначена для получения данных из API. Затем я передаю эту функцию в значение props ProductContext.Provider. Таким образом, значение fetchProducts будет доступно всем дочерним элементам ProductContext.Provider.
Последний шаг для доступа к этим значениям из провайдера – использование хука useContext для предоставления доступа к значениям из ProductContext.Provider.
//product_context.js
export const ProductsProvider = ({ children }) => {
const fetchProducts = async () => {
let response = {};
try {
response = await axios.get(url);
let products = response.data;
} catch (error) {
console.log({ error });
}
};
return (
<ProductContext.Provider value={{fetchProducts}}>
{children}
</ProductContext.Provider>
);
};
export const useProductContext = () => {
return useContext(ProductContext);
};
Мы создаем пользовательский хук под названием useProductContext, который возвращает значения из ProductContext.Provider.
Таким образом, когда мы хотим использовать значения из нашего контекстного провайдера, мы просто должны деструктурировать значения из нашего пользовательского хука, как показано ниже.
//Product.js Page
import { useProductContext } from "../products_context";
const { featuredProducts } = useProductContext();
До тех пор, пока ваш компонент является дочерним компонентом функции ProductsProvider, ваш компонент будет иметь доступ к этим значениям.
Чтобы показать пример, я использую Nextjs для своего проекта, и с помощью Nextjs ниже приведен пример того, как я прикреплю свой компонент ProductsProvider, чтобы все мое приложение получало значения контекста.
//_app.js
import { ProductsProvider } from "../products_context";
function MyApp({ Component, pageProps }) {
return (
<ProductsProvider>
<Component {...pageProps} />
</ProductsProvider>
);
}
export default MyApp;
В NextJS тегом является текущая отображаемая страница, поэтому каждая страница в моем приложении будет иметь доступ к контекстным значениям.
Надеюсь, это дало вам ясное представление о том, как использовать React Context API. Во второй части мы рассмотрим добавление useReducer для управления состоянием наших данных, а также то, как мы передаем значение состояния всем нашим компонентам.