Если задуматься, поток данных сверху вниз — это то, что дало реакту суперсилу.
- У вас больше контроля над данными. Нет больше ранних дней JS, когда вы прочесывали кучи JS-файлов и выясняли, что изменило ваше состояние.
- Легче отлаживать, так как вы знаете, что откуда берется.
Но что если мы создаем глубоко вложенное приложение?
const App = () => {
return (
<div>
App Contents
<Toolbar theme={store.theme} />
</div>
);
};
const Toolbar = ({ theme }) => {
return (
<div>
<Button theme={theme} label="Button 1" />
<Button theme={theme} label="Button 2" />
</div>
);
};
const Button = ({ theme, label }) => {
return (
<button style={{ backgroundColor: theme === "dark" ? "black" : "white" }}>
{label}
</button>
);
};
Это называется prop-drilling, и это становится еще хуже, если у вас больше слоев компонентов между источником данных и пользователем. Как решить эту проблему? React Context в помощь!!!
Решение проблемы prop drilling с помощью Context API
Context API позволяет транслировать состояние/данные нескольким компонентам, обернув их провайдером контекста. Передайте ваше состояние как атрибут значения в contextProvider, после чего дочерние компоненты могут подключиться к этому провайдеру с помощью потребителя контекста или хука useContext.
Шаг 1: Создание контекста
// ThemeContext.jsx
import React from "react";
const ThemeContext = React.createContext();
export default ThemeContext;
Шаг 2: Провайдер контекста:
Теперь мы можем обернуть всех потребителей контекста с помощью провайдера контекста и передать значение, которое мы хотим «транслировать».
const App = () => {
return (
<ThemeContext.Provider value={{ theme: store.theme }}>
App Contents
<Toolbar />
</ThemeContext.Provider>
);
};
Теперь, как нам получить доступ к теме из ее потомков Toolbar, Button?
Шаг 3: Потребитель контекста: useContext
Чтобы получить доступ к контексту, мы используем хук useContext из любого потомка компонента App
.
import React from "react";
import { ThemeContext } from "./ThemeContext";
const Button = ({ theme, label }) => {
const { theme } = React.useContext(ThemeContext);
return (
<button style={{ backgroundColor: theme === "dark" ? "black" : "white" }}>
{label}
</button>
);
};
Здесь наш вывод остался прежним, но код под ним стал немного стройнее и чище.
Вот и все! Надеюсь, я помог прояснить, зачем вам нужен контекст и как его реализовать. Не стесняйтесь задавать вопросы, оставлять комментарии и любые предложения.