Когда в проекте React (Next.js) требуется внедрить глобальное состояние, которое должно быть доступно в различных компонентах не только для чтения, но и для изменения, то на ум приходят такие решения, как Zustand, Jotai, Nanostore и т.п. Каждая из этих библиотек имеет свои преимущества и недостатки, но в этой статье речь пойдет немного о другом.
В большинстве случаев для внедрения глобального состояния можно обойтись стандартным функционалом React, добавив в проект всего один файл из нескольких строк кода. А подключение сторонней библиотеки является неоправданным и избыточным.
1. Создаём провайдер глобального состояния ValueProvider, которое должно быть доступно для чтения value и изменения setValue() в любом месте проекта:
"use client";
import { createContext, useContext, useState } from "react";
const ValueContext = createContext({
value: 0,
setValue: null,
});
export default function ValueProvider({ children }) {
const [value, setValue] = useState(0);
return (
<ValueContext value={{ value: value, setValue: setValue }}>
{children}
</ValueContext>
);
}
export function useValue() {
return useContext(ValueContext);
}В этом примере глобальное состояние value является числовым, но может быть любого типа, включая сложные объекты.
2. Подключаем провайдер глобального состояния в корневом макете:
import "./globals.css";
import ValueProvider from "@/lib/value-provider";
export default function RootLayout({ children }) {
return (
<html lang="ru">
<body>
<ValueProvider>{children}</ValueProvider>
</body>
</html>
);
}Теперь глобальное состояние value и функция его изменения setValue() будут доступны в любом месте проекта.
3. Пример использования глобального состояния value в компоненте:
"use client";
import { useValue } from "@/lib/value-provider";
export default function Component() {
const { value, setValue } = useValue();
return <button onClick={() => setValue((n) => n + 1)}>Value: {value}</button>;
}В этом компоненте импортируются как само глобальное состояние value, так и функция его изменения setValue(). Но это решение позволяет в одних компонентах импортировать только значение глобального состояния value, а в других только функцию его изменения setValue().