Контекст в React
Контекст (Context) в React — это способ управления глобальным состоянием в приложении.
Его можно использовать совместно с хуком useState, чтобы легко делиться состоянием между глубоко вложенными компонентами, чего трудно добиться только с помощью useState.
Проблема
Состояние должно находиться в самом высоком родительском компоненте, которому необходимо получить доступ к этому состоянию.
Для иллюстрации предположим, что у нас есть многоуровневая иерархия компонентов, где верхний и нижний компоненты нуждаются в доступе к состоянию.
Без использования Context нам придётся передавать состояние через промежуточные компоненты в виде "пропсов". Это называется пробиванием пропсов (prop-drilling).
Пример
Передача "пропсов" через вложенные компоненты:
import { useState } from 'react';
import { createRoot } from 'react-dom/client';
function Component1() {
const [user, setUser] = useState("Linus");
return (
<>
<h1>{`Привет, ${user}!`}</h1>
<Component2 user={user} />
</>
);
}
function Component2({ user }) {
return (
<>
<h1>Component 2</h1>
<Component3 user={user} />
</>
);
}
function Component3({ user }) {
return (
<>
<h1>Component 3</h1>
<h2>{`И снова привет, ${user}!`}</h2>
</>
);
}
createRoot(document.getElementById('root')).render(
<Component1 />
);
Даже если компонент 2 не нуждался в состоянии, он вынужден передавать его дальше, чтобы обеспечить доступ к состоянию компоненту 3.
Решение
Решение состоит в создании контекста.
Создание контекста
Чтобы создать контекст, нужно импортировать createContext и инициализировать его:
import { useState, createContext, useContext } from 'react';
import { createRoot } from 'react-dom/client';
const UserContext = createContext();
Далее мы используем провайдер контекста для обертывания деревьев компонентов, нуждающихся в доступе к состоянию контекста.
Провайдер контекста
Оберните дочерние компоненты в провайдер контекста UserConter.Provider и предоставьте им значение состояния.
function Component1() {
const [user, setUser] = useState("Linus");
return (
<UserContext.Provider value={user}>
<h1>{`Привет, ${user}!`}</h1>
<Component2 />
</UserContext.Provider>
);
}
Теперь все компоненты в дереве получат доступ к контексту пользователя.
Использование хука useContext
Чтобы использовать контекст в дочернем компоненте, нужно обратиться к нему с помощью хука useContext.
Сначала добавьте useContext в оператор импорта:
import { useState, createContext, useContext } from "react";
Тогда вы сможете получить доступ к контексту пользователя во всех компонентах:
function Component3() {
const user = useContext(UserContext);
return (
<>
<h1>Component 3</h1>
<h2>{`И снова привет, ${user}!`}</h2>
</>
);
}
Полный пример
Полный пример использования React Context:
Пример
import { useState, createContext, useContext } from 'react';
import { createRoot } from 'react-dom/client';
const UserContext = createContext();
function Component1() {
const [user, setUser] = useState("Linus");
return (
<UserContext.Provider value={user}>
<h1>{`Привет, ${user}!`}</h1>
<Component2 />
</UserContext.Provider>
);
}
function Component2() {
return (
<>
<h1>Component 2</h1>
<Component3 />
</>
);
}
function Component3() {
const user = useContext(UserContext);
return (
<>
<h1>Component 3</h1>
<h2>{`И снова привет, ${user}!`}</h2>
</>
);
}
createRoot(document.getElementById('root')).render(
<Component1 />
);