Что умеет Context API в ReactJS
Development | Комментировать запись
В мире, где существует множество различных интерфейсных фреймворков, всегда трудно сделать выбор. Что лучше: использовать популярный Angular или выучить VueJS?
К счастью, сегодня у нас есть ReactJS, разработанный компанией Facebook фреймворк, который взял мир фронтенд фреймворков штурмом. React объединяет компоненты, виртуальный DOM и JSX и, похоже, удовлетворяет потребности очень многих разработчиков и охватывает широкую аудиторию.
Context API, о котором и пойдет речь в этой статье, был представлен в React 16.3 как «метод передачи данных через дерево компонентов без необходимости вручную передавать реквизиты на каждом уровне».
Что ж, звучит здорово! Давайте разберемся, как это работает.
Свойства и состояние
В React есть две очень важные вещи, которые нужно понять – это свойства и состояние (props и state соответственно).
- Свойства — это данные, которые передаются компоненту из родительского компонента.
- Состояние — это данные, которыми управляет компонент. Если каждый компонент имеет свое собственное состояние, как мы можем поделиться этой информацией с другим компонентом? Тут можно использовать свойства, но их можно передавать только между родительским и дочерним компонентами.
Так что же делать, если у нас много уровней компонентов?
Пробрасывание и Context API
Пробрасывание (или prop-drilling) – это трудоемкий процесс, в рамках которого одни и те же данные отправляются почти на каждом уровне из-за требований финального уровня. Проще говоря, это явная передача значений через представление приложения.
Давайте взглянем на пример пробрасывания и посмотрим, чем может быть полезен Context API. В этом примере мы увидим, как можно передавать информацию одного компонента к его дочернему компоненту, а затем к дочернему компоненту этого компонента и так далее.
const Lowest = (props) => ( <div className="lowest">{props.name}</div> ) const Middle = (props) => ( <div className="middle"> <Lowest name={props.name} /> </div> ) class Highest extends Component { state = { name: "Context API" } render() { return <div className="highest"> {this.state.name} <Middle name={this.state.name} /> </div> } }
Именование в этом примере условное, просто оно лучше демонстрирует способность контекста передаваться во вложенные компоненты. Более реалистичный сценарий может произойти в пользовательском интерфейсе: CardGrid -> CardContent -> CardFooter -> LikeButton.
Вернемся к нашему примеру. Вот так будут вложены компоненты Highest -> Middle -> Lowest:
<Highest> <Middle> <Lowest> {/* здесь должен быть наш контент, но мы не хотим, чтобы он пробрасывался через все уровни */} </Lowest> </Middle> </Highest>
Обратите внимание, для того, чтобы Highest и Lowest могли взаимодействовать, им нужно, чтобы сообщение прошло через Middle.
Что ж, у нас есть React Context, который может позаботиться обо всей работе за нас.
Как работает Context API
React Context API предоставляет глобальное состояние для всего приложения.
Чтобы определить данные, которые мы хотим отправлять, мы должны начать с поставщика контекста (<Provider/>). Затем определяется потребитель контекста (<Consumer/>), который захватывает эти данные и использует их там, где они вызываются.
Проще говоря, Context API предоставляет возможность объявить состояние один раз, а затем использовать эти данные через потребителя контекста в каждой части приложения, где эти данные необходимы.
Звучит невероятно! Что ж, давайте посмотрим, как мы могли бы применить этот API в простом приложении React.
Сборка простого приложения с Context API
Давайте попробуем создать базовое приложение React, которое передает имя от одного компонента другому компоненту, который (так уж получилось) не является дочерним компонентом. Здесь у нас будет три разных уровня: самый высокий компонент, имя которого хранится в состоянии, средний компонент, а затем (логично) самый низкий компонент.
Приложение будет отправлять имя от высшего компонента к низшему, не обращаясь к при этом к посредничеству компонента, который находится между ними. Откройте любой редактор кода, который вам нравится, и приступим к кодированию.
Во-первых, для работы приложения понадобится зависимость react. Добавьте ее в свои зависимости. Если вы работаете в текстовом редакторе, выполните следующие шаги, чтобы установить его:
- Установите npm глобально на свой компьютер, если он у вас еще не установлен:
npm install —save react
- Проверьте файл package.json на наличие зависимости react.
Всякий раз, когда мы создаем приложение React, мы должны импортировать свои зависимости в главный файл .js, иначе он не будет знать, как их использовать. Итак, давайте импортируем то, что нам нужно, в верхней части файла index.js:
import React, { Component } from 'react';
Зависимости импортированы, теперь давайте перейдем к компоненту. Для удобочитаемости мы объявим контекст в переменной. Под импортом сделайте следующее:
const AppContext = React.createContext()
Уровни компонентов
Итак, компонент Highest будет иметь состояние, а состояние будет иметь имя, которое мы хотим передать компоненту Lowest, не обращаясь к компоненту Middle. Вот наш компонент Highest:
class Highest extends Component { state = { name : “React Context API”, } render() { return ( <AppContext.Provider value={this.state}> {this.props.children} </AppContext.Provider> ) } }
Дочерний компонент будет называться Middle:
const Middle = () => ( <div> <p>I’m the middle component</p> <Lowest /> </div> )
В свою очередь, его дочерний компонент будет называться Lowest:
const Lowest = () => ( <div> <AppContext.Consumer> {(context) => context.name} </AppContext.Consumer> </div> )
Как видите, у нас есть состояние Highest, которое мы хотим передать в Lowest. Кроме того, у нас есть статическое свойство, которое позволит нам объявить, каким должен быть наш контекст (здесь это React Context API).
Provider хранит эти данные, чтобы знать, что передавать другим компонентам, когда они запросят эти данные. В компоненте Lowest есть Consumer, которому нужны эти данные, и он сможет получить их без посредничества компонента Middle.
Когда лучше не использовать Context API?
Context API отлично подходит для простого пробрасывания. В более масштабных приложениях с несколькими (и более сложными) состояниями, редукторами и т.д. Redux справится лучше, чем Context API.
Также нет необходимости использовать Context API во всем приложении – иначе код может стать слишком беспорядочным. Будьте изобретательны, не используйте Context API, просто чтобы чуть сократить код.
Заключение
React Context API довольно крут. Но лучше не используйте его, если вы не знаете, насколько полезно это будет для вашего кода. Возможно, вам вполне подойдет и Redux.
Полный код мануала вы найдете здесь.
Читайте также: Введение в Redux: основные понятия
Tags: API, React