Оглавление
Доброго времени суток, друзья. Сегодня поговорим о контексте в React и работе с хуком useContext. Разберем контекст в React и какую проблему он решает. На примере передачи данных между двумя независимыми компонентами посмотрим на практическую сторону использования useContext.
Видео на эту тему.
Что такое контекст?
онтекст в React это способность передачи данных через дерево компонентов, минуя прокидывание данных через пропсы от одного компонента к другому. Если посмотреть на историю развития React, то мы увидим, что до создания Flux, Reflux, Redux и Mobx решений все данные передавались от самого верхнего компонента к нижним через пропсы, иногда минуя огромные цепочки связанных компонентов. Это было крайне неудобное решение, если приложение насчитывало сотни, а иногда даже и тысячи связанных компонентов. Чтобы решить данною проблему, разработчики React придумали Context API, благодаря которому процесс передачи стал гораздо проще и лаконичнее.
Для создания контекста достаточно воспользоваться методом React.createContext, он имеет единственный параметр, в который можно передать дефолтное значение или объект для получения дочерних компонентов через контекст.
Пример:
const context = React.createContext('value');
Вызывая React.createContext, мы получаем объект, который содержит два компонента, позволяющие взаимодействовать с ним.
Компонент Provider
После создания контекста, его требуется использовать совместно с компонентом Provider, который позволяет дочерним компонентам подписаться на его изменения. Если проще, то благодаря компоненту Provider все дочерние компоненты могут получить значения, которые мы ему передаем.
Пример:
<Сontext.Provider value={"value"}>
Данный компонент имеет пропс value, в котором можно указать значение для передачи всем дочерним компонентам.
Компонент Consumer
Второй компонент, который находится в объекте после вызова React.createContext является Consumer. Он предназначен для подписи на изменение контекста в функциональном компоненте. В качестве дочернего компонента он принимает функцию, которая получает контекст и возвращает React компонент. Благодаря компоненту Consumer у нас есть возможность получать значения из контекста в компонентах.
Пример:
<Context.Consumer>
{ value = > <div>value</div> }
</Context.Consumer>
Несколько контекстов
Часто одного контекста в приложении бывает не достаточно и требуется использовать несколько контекстов. Для этого как правило просто оборачивают один Provider другим и передают в них нужные значения.
Пример:
<Context.Provider value={1}>
<TwoContext.Provider value={2}>
<Page />
</TwoContext.Provider>
</Context.Provider>
Тоже самое делают и с Consumer для получения значений в дочерних компонентах.
Пример:
<Context.Consumer>
{one => (
<TwoContext.Consumer>
{two => (
<Page one={one} two={two} />
)}
</TwoContext.Consumer>
)}
</Context.Consumer>
Получение контекста в Class компонентах
Для получения контекста в Class компоненте необходимо использовать свойство contextType, имеющееся в самом классе, и присвоить объект, возвращающий контекст. После чего, используя свойства this.context, можно получить доступ к его значениям уже внутри класса.
Пример:
class ComponentOne extends React.Component {
componentDidMount() {
const value = this.context;
}
componentDidUpdate() {
const value = this.context;
}
render() {
const value = this.context;
}
}
ComponentOne.contextType = Context;
Для чего нужен useContext?
После изучения всей базовой теории по контексту можно наконец-то перейти к хукам. Основная задача хуков в React это упрощение API с целью написания меньшего количества кода и удобства. Хук useContext занимается именно тем, что уменьшает количество написанного кода для взаимодействия с контекстом в функциональных компонентах.
Пример:
const value = useContext(Context)
Хук имеет один параметр, в который требуется передать объект контекста, получаемый при вызове React.createContext.
Важно! При изменении значений в контексте, компонент, который содержит useContext, всегда будет перерендериваться.
useContext на практике
Давайте создадим компонент, в котором у нас будет храниться контекст и два дочерних компонента. При нажатии на кнопку в одном компоненте, будет происходить изменение текста в другом. Данный пример поможет лучше понять, как работать с контекстом, используя useContext.
Пример (App.js):
import React, { useState } from "react";
import { Context } from "./Context.js";
import ComponentA from "./ComponentA";
import ComponentB from "./ComponentB";
export default function App() {
const [context, setContext] = useState("default context value");
return (
<Context.Provider value={[context, setContext]}>
<ComponentA />
<ComponentB />
</Context.Provider>
);
}
Пример (Context.js):
import React from "react";
export const Context = React.createContext();
Пример (ComponentA.js):
import React, { useContext } from "react";
import { Context } from "./Context";
export default function ComponentA() {
const [context, setContext] = useContext(Context);
return (
<div>
ComponentA:
<button onClick={() => setContext("New Value")}>
Change Context Value
</button>
</div>
);
}
Пример (ComponentB.js):
import React, { useContext } from "react";
import { Context } from "./Context";
export default function ComponentB() {
const [context, setContext] = useContext(Context);
return <div>ComponentB: {context}</div>;
}
Давайте разберем по шагам, что происходит в этом примере. В Context.js создается сам контекст, а в App.js импортируются два компонента и контекст, которым они оборачиваются, c передачей в value начального состояния (context) и функции для его изменения (setContext).
Два дочерних компонента импортируют в себя контекст, используя хук useContext и посредством деструктуризации вытаскивается значение и функция для ее изменения.
При нажатии на кнопку в компоненте ComponentA происходит изменение значения контекста, благодаря useContext в компоненте ComponentB происходит его моментальное перерендеривание и, как результат в нем отображается значение контекста.
Заключение
Сегодня мы разобрали понятие контекста в React и на примерах посмотрели практическое применение useContext. Благодаря использованию useContext работа с контекстом стала более лаконичной и простой. Помните, использование контекста в вашем приложении может усложнить повторное использование компонентов, и в качестве альтернативы вы можете использовать более простое и эффективное решение, а именно композицию компонентов. Надеюсь, что данная статья была вам полезна. Учитесь, думайте, пишите код. Удачного кодинга, друзья!
Подписывайтесь на наш канал в Telegram и на YouTube для получения самой последней и актуальной информации.
Комментарии: