DevGang
Авторизоваться

Совместное использование состояния с помощью React's Context API

Глобальное состояние в React является синонимом таких библиотек, как Redux. Если вам когда-либо приходилось делить состояние, например текущий маршрут или данные из API, с несколькими компонентами, то вы, возможно, использовали Redux.

Более новые версии React (16.3+) включают встроенный способ совместного использования состояния, что означает отсутствие необходимости извлекать внешнюю библиотеку. Это известно как React Context API, и его может быть немного сложно понять. Я надеюсь предоставить упрощенное объяснение и учебное пособие, чтобы вы могли быстро добавить глобальное состояние в любое из ваших приложений на React.

Проблема, которую мы пытаемся решить

Прежде чем я углублюсь в Context API, позвольте мне сначала описать проблемный сценарий.

Допустим, у нас есть панель инструментов, где пользователь может обновить свое имя пользователя. Имя пользователя отображается по всей панели инструментов, что означает, что имя пользователя будет сохранено в состоянии компонента, а затем передано другим компонентам через props.

Без Context API мы бы сделали что-то вроде этого:

class Dashboard extends React.Component {
 state = { username: '' }; render() {
   return (
     
{ this.setState({ username: newUsername }); }} />
); } }

Имя пользователя сохраняется в состоянии компонента Dashboard, а затем передается с помощью username в оба компонента и . Дополнительный параметр передается в форму для обновления состояния, которое затем повторно отображает информационную панель с новым именем пользователя.

Трудно увидеть какие-либо проблемы с этим прямо сейчас. Подумайте, что может произойти, когда мы добавим на панель инструментов больше компонентов, которые глубоко вложены.


 
   
     
       

Need to show username here...

В этом примере я пытаюсь показать, что - это 3 уровня компонентов глубоко внутри панели мониторинга. Чтобы передать ему имя пользователя, нам нужно сделать то, что называется «prop drilling»:


 
   
     
       

Hello {this.props.username}!

Это может стать чрезвычайно утомительным, так как мы добавляем больше состояний и вложенных компонентов. Кроме того, есть шанс, что нам нужно получить доступ к имени пользователя за пределами панели мониторинга.

Как использовать Context API

Решением этой проблемы является использование встроенного React Context API.

Это позволяет вам избежать подробного пробрасывания параметров, что означает, что в нашем предыдущем примере компонент будет иметь прямой доступ к состоянию имени пользователя, которое было изначально сохранено в компоненте .

Примечание: полностью рабочий пример доступен на CodeSandbox.

Создание поставщиков и потребительских компонентов

Давайте начнем с создания файла для вашего контекста. Я назову это user-context.js.

В этот файл добавьте следующее:

import React, { createContext } from 'react';

const UserContext = createContext({
 username: '',
 updateUsername: () => {},
});

export class UserProvider extends React.Component {
 updateUsername = newUsername => {
   this.setState({ username: newUsername });
 };
 state = {
   username: 'user',
   updateUsername: this.updateUsername,
 };
 render() {
   return (
     
       {this.props.children}
     
   );
 }
}

export const UserConsumer = UserContext.Consumer;

Давайте разберем этот файл.

Сначала пользовательский контекст создается с использованием createContext(). Здесь значения будут переопределены UserProvider.

Затем мы создаем компонент UserProvider, который будет служить родительским компонентом для хранения и управления общим состоянием. Думайте об этом как о эквиваленте компонента в нашем самом раннем примере.

Наконец, мы экспортируем компонент UserConsumer, который позволит компонентам получить доступ к общему состоянию.

Использование провайдера

Компонент должен охватывать все компоненты, которые совместно используют состояние. Самый простой способ - добавить его в основной компонент приложения, который обычно отображается в DOM от React.

import React from 'react';
import ReactDOM from 'react-dom';
import UserMessage from './UserMessage';
import SettingsForm from './SettingsForm';
import { UserProvider } from './user-context';

function App() {
 return (
   
     
     
   
 );
}

const rootElement = document.getElementById('root');

ReactDOM.render(, rootElement);

Мы также импортируем два других компонента: UserMessage и SettingsForm. Эти два компонента будут иметь доступ к общему состоянию пользователя.

Использование потребителя для чтения состояния

Одним из вариантов использования общего состояния является его отображение. В этом случае мы отобразим текущее имя пользователя. Создайте файл с именем UserMessage.js и добавьте в него следующее:

import React from 'react';
import { UserConsumer } from './user-context';

export default function UserMessage() {
 return (
   
     {({ username }) => 

Welcome {username}!

}
); }

В этом файле мы создали компонент UserMessage, который отображает сообщение «Welcome username». Имя пользователя извлекается из компонента UserConsumer, который экспортируется из user-context.js.

Внутри мы передаем то, что называется реквизитом рендера. В данном случае это функция, в которой мы можем захватить части нашего состояния и что-то сделать с ним.

Использование потребителя для обновления состояния

Другой вариант использования общего состояния - обновить его. В этом случае мы предоставим пользователю форму для обновления своего имени пользователя. Создайте файл с именем UserSettings.js и добавьте в него следующее:

import React from 'react';
import { UserConsumer } from './user-context';

export default function UserSettings() {
 return (
   
     {({ updateUsername }) => (
       

Settings

{ updateUsername(event.target.value); }} />
)}
); }

Это похоже на предыдущий пример, за исключением того, что вместо получения имени пользователя мы используем функцию updateUsername для его обновления.

В итоге

Если вы запутались в этом вопросе, я настоятельно рекомендую вам посмотреть на работающий пример CodeSandbox, который объединяет все.

Кроме того, вот краткий обзор основных понятий:

  • Компонент провайдера оборачивает все приложение для управления общим состоянием.
  • Потребительский компонент используется для доступа или обновления общего состояния.
  • Файл user-context.js экспортирует оба этих компонента, и общее состояние сохраняется в компоненте .
  • Компоненты и считывают и обновляют общее состояние, просто импортируя и используя компонент .
  • Вы можете читать и обмениваться информацией о состоянии из любого места в вашем приложении, предполагая, что оборачивает все ваше приложение.

Вот и все. Не стесняйтесь использовать эту функцию, чтобы поделиться состоянием для навигации, модальных окон или даже данных. Сила в твоих руках 💪

#React
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу