Учебное пособие по React Context: полное руководство с практическими примерами

Примечание редактора: В последний раз эта статья обновлялась в феврале 2025 года Виджитом Айлом (Vijit Ail), чтобы добавить варианты использования и подробные примеры, соответствующие последним обновлениям React 19, расширить комментарии к Redux vs Context и удалить устаревшую информацию, связанную с компонентом class.

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

Контекст React был представлен в версии React v.16.3. Он позволяет нам передавать данные по нашим деревьям компонентов, позволяя нашим компонентам взаимодействовать и обмениваться данными на различных уровнях. В этом руководстве мы рассмотрим все, что вам нужно знать об эффективном использовании контекста. Давайте погрузимся в это с головой.

Что такое контекст React?

Передача реквизита через каждый промежуточный компонент может быть утомительной и усложнить поддержку вашего кода. Вот почему был введен контекст React.

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

Как использовать контекст React

  1. Создайте контекст - Сначала вы создаете контекст с помощью функции createContext(). При этом создается специальный объект, который хранит состояние, которым вы хотите поделиться
  2. Укажите контекст Вы добавляете компонент <Контекст /> в верхнюю часть дерева компонентов, которому требуется доступ к общему состоянию
  3. Используйте контекст. Любой дочерний компонент, заключенный в компонент <Context>, может получить доступ к общим данным с помощью функции useContext() или <Context.Компонент Consumer />

Понимание функции useContext()

Функция useContext() в React - это полезная функция, которая позволяет компонентам легко получать доступ к общим данным без необходимости передавать реквизиты через дерево компонентов. Она может считывать контекст и подписываться на него непосредственно из любого компонента.

Вот основное использование функции useContext():

// Assume MyContext is created somewhere in your app

const MyComponent = () => {
    const contextValue = useContext(MyContext);
    // you can use contextValue anywhere in this component
}

Вызывая useContext(MyContext), вы получаете текущее значение от ближайшего поставщика <MyContext />, расположенного над вашим компонентом в дереве. Если поставщик не найден, функция useContext() возвращает значение по умолчанию, определенное при создании MyContext.

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

Варианты использования для контекста React

При работе с React существует множество сценариев, в которых контекст может значительно облегчить вашу жизнь.

Темы

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

Вошедший в систему пользователь

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

Маршрутизация

Популярные библиотеки маршрутизации, такие как react-router и wouter, используют контекст для отслеживания текущего состояния маршрутизации. Это позволяет приложению узнать, какой маршрут активен в данный момент, и соответствующим образом отобразить компонент маршрута.

Государственное управление

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

Использование контекста React с примерами

Давайте рассмотрим некоторые варианты использования React Context в контексте реального мира:

Базовый пример

Давайте посмотрим на простую реализацию того, как мы можем управлять светлыми и темными темами, используя контекст React.

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

const ThemeContext = createContext();

Далее мы создадим компонент <ThemeProvider />, который объединяет все наше приложение и предоставляет контекст темы для всех дочерних компонентов:

const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState("light");

  const toggleTheme = () => {
    setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
  };

  return (
    <ThemeContext value={{ theme, toggleTheme }}>
      <div className={`app-theme-${theme}`}>{children}</div>
    </ThemeContext>
  );
};

В приведенном выше коде мы используем компонент <ThemeContext />, чтобы сделать тему и toggleTheme() доступными для любого компонента, который использует контекст.

Теперь создайте компонент <ThemeSwitcher />, который будет предоставлять пользователям кнопку для переключения между темами. Мы используем функцию useContext() для доступа к теме и функции toggleTheme(), предоставляемой компонентом <ThemeProvider />:

const ThemeSwitcher = () => {
  const { theme, toggleTheme } = useContext(ThemeContext);

  return (
    <button onClick={toggleTheme}>
      Switch to {theme === "light" ? "dark" : "light"} mode
    </button>
  );
};

Давайте создадим компонент <Header /> для отображения заголовка приложения и компонент <ThemeSwitcher />:

const Header = () => (
  <header>
    <h1>My App</h1>
    <ThemeSwitcher />
  </header>
);

И, наконец, мы объединяем компонент <Main /> с <ThemeProvider />, чтобы все дочерние компоненты имели доступ к контексту темы:

const Main = () => {
  const { theme } = useContext(ThemeContext);

  return (
    <div className={theme}>
      <Header />
      <main>
        <p>Hello World!</p>
      </main>
    </div>
  );
};

export default function App() {
  return (
    <ThemeProvider>
      <Main />
    </ThemeProvider>
  );
}

Всплывающие сообщения

Другим распространенным способом использования React Context является отображение всплывающих сообщений. Давайте рассмотрим, как React Context помогает отображать всплывающие сообщения из разных компонентов.

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

// ToastContext.jsx
import React, { createContext, useState, useContext } from "react";

const ToastContext = createContext();

export const ToastProvider = ({ children }) => {
  const [toasts, setToasts] = useState([]);

  const addToast = (message) => {
    const id = Date.now();
    setToasts([...toasts, { id, message }]);

    setTimeout(() => {
      setToasts((currentToasts) =>
        currentToasts.filter((toast) => toast.id !== id)
      );
    }, 3000);
  };

  return (
    <ToastContext value={{ addToast }}>
      {children}
      <div className="toast-container">
        {toasts.map((toast) => (
          <div key={toast.id} className="toast">
            {toast.message}
          </div>
        ))}
      </div>
    </ToastContext>
  );
};

export const useToast = () => useContext(ToastContext);

Компонент <ToastProvider /> управляет состоянием тостов. Он отображает все тосты в фиксированном контейнере. Он также предоставляет функцию addToast(), которая отображает новые сообщения о тостах и автоматически удаляет их через три секунды с помощью метода setTimeout().

В следующем фрагменте кода есть несколько дочерних компонентов, таких как <Navbar />, <Profile />, <Home />, которые используют функцию addToast() для запуска всплывающих сообщений:

// App.js
import { ToastProvider, useToast } from "./ToastContext";
import "./styles.css";

// Navbar Component
const Navbar = () => {
  const { addToast } = useToast();

  const handleLogout = () => {
    addToast("You have been logged out.");
  };

  return (
    <nav>
      <h1>Toast Example</h1>
      <button onClick={handleLogout}>Logout</button>
    </nav>
  );
};

// Home Component
const Home = () => {
  const { addToast } = useToast();

  const handleClick = () => {
    addToast("Welcome to the Home Page!");
  };

  return (
    <div>
      <h2>Home</h2>
      <button onClick={handleClick}>Show Home Toast</button>
    </div>
  );
};

// Profile Component
const Profile = () => {
  const { addToast } = useToast();

  const handleUpdate = () => {
    addToast("Profile updated successfully!");
  };

  return (
    <div>
      <h2>Profile</h2>
      <button onClick={handleUpdate}>Update Profile</button>
    </div>
  );
};

// Dashboard Component with Nested Components
const Dashboard = () => {
  return (
    <div>
      <h1>Dashboard</h1>
      <Home />
      <Profile />
    </div>
  );
};

export default function App() {
  return (
    <ToastProvider>
      <Navbar />
      <Dashboard />
    </ToastProvider>
  );
}

Пользовательский хук useToast() повышает возможность повторного использования кода, предоставляя простой API для доступа к функциональности toast в любом дочернем компоненте:

// props drilling
<Navbar addToast={addToast} />
<Dashboard addToast={addToast} />
<Home addToast={addToast} />
<Profile addToast={addToast} />

Вместо того, чтобы передавать функцию addToast() в качестве вспомогательного средства, Context позволил дочерним компонентам напрямую запускать всплывающие сообщения. Это делает подход масштабируемым по мере добавления дополнительных компонентов в ваше приложение.

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

Использование контекста с помощью use() Крюк

Use() Хук в React - это специальный API, созданный для упрощения взаимодействия между компонентами и асинхронными данными и контекстом. Он обеспечивает более гибкий подход, чем традиционный хук useContext(), позволяя нам условно считывать значения из контекста или обрабатывать обещания непосредственно в компоненте.

В этом примере мы рассмотрим, как use() Hook, можно использовать для доступа к пользовательским данным из значения контекста.

В компоненте <UserProvider /> у нас есть макет пользовательского объекта со свойствами электронной почты и мобильных устройств. Этот компонент облекает свои дочерние элементы в <UserContext />, предоставляя пользовательские данные любому компоненту внутри него.

Пользовательский хук useUser() определен для доступа к значению UserContext с помощью функции use() Крюк. Этот пользовательский хук можно использовать внутри условия if или в цикле, поскольку он использует use() Хук под капотом:

// UserContext.jsx
import React, { createContext, use } from "react";

export const UserContext = createContext(null);

export const UserProvider = ({ children }) => {
  const user = {
    email: "[email protected]",
    mobile: "123-456-7890",
  };

  return <UserContext value={user}>{children}</UserContext>;
};

export const useUser = () => use(UserContext);

В App.jsx мы создали компонент <ProfileDetails /> для отображения пользовательских данных. Изначально мобильные устройства и электронная почта замаскированы для отображения конфиденциальной информации. Переменная состояния showData используется для отслеживания того, следует ли снимать маску с данных. Когда флаг showData имеет значение true, пользовательские данные обновляются путем доступа к значению с помощью пользовательского перехватчика useUser():

// App.jsx
import { useState } from "react";
import "./styles.css";
import { UserProvider, UserContext, useUser } from "./UserContext";

const ProfileDetails = () => {
  let mobile = "****";
  let email = "****";
  const [showData, setShowData] = useState(false);

  const toggleData = () => {
    setShowData((prev) => !prev);
  };

  if (showData) {
    const user = useUser();
    mobile = user.mobile;
    email = user.email;
  }

  return (
    <div>
      <h2>Profile Details</h2>
      <button onClick={toggleData}>
        {showData ? "Hide Data" : "Show Data"}
      </button>
      <p>Mobile: {mobile}</p>
      <p>Email: {email}</p>
    </div>
  );
};

export default function App() {
  return (
    <UserProvider>
      <ProfileDetails />
    </UserProvider>
  );
}

В этом примере мы увидели, как новый хук use() можно использовать для доступа к контексту React и условного отображения или скрытия данных в зависимости от взаимодействия с пользователем.

Использование с редуктором

В этом примере мы увидим, как [useReducer](https://blog.logrocket.com/react-usereducer-hook-ultimate-guide/) Может быть использован в контексте React. Мы создадим простое приложение для корзины покупок, которое позволит пользователям добавлять, удалять и изменять количество товаров в корзине.

Давайте начнем с определения контекста:

const CartContext = createContext();

CartContext предоставит дочерним компонентам функции состояния и обновления элементов корзины.

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

const ADD_TO_CART = "ADD_TO_CART";
const REMOVE_FROM_CART = "REMOVE_FROM_CART";
const INCREMENT_QUANTITY = "INCREMENT_QUANTITY";
const DECREMENT_QUANTITY = "DECREMENT_QUANTITY";

Эти константы будут использоваться функцией reducer для обработки отправленных действий.

Далее мы определим состояние корзины. Корзина запускается как пустой массив и будет обновляться по мере добавления товаров пользователем:

const initialState = {
  cart: [],
};

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

  • ДОБАВИТЬ В КОРЗИНУ... Добавьте товар или увеличьте его количество, если он уже существует
  • УДАЛИТЬ товар ИЗ корзины - ”Удалить товар из корзины"
  • УВЕЛИЧИТЬ КОЛИЧЕСТВО... Увеличить количество продукта
  • УМЕНЬШЕНИЕ_КАЧЕСТВА - Уменьшение количества продукта

Вот наша функция редуктора:

function reducer(state, action) {
  switch (action.type) {
    case ADD_TO_CART: {
      const existingProductIndex = state.cart.findIndex(
        (item) => item.id === action.product.id
      );

      if (existingProductIndex >= 0) {
        const newCart = [...state.cart];
        newCart[existingProductIndex].quantity += 1;
        return { ...state, cart: newCart };
      }

      return {
        ...state,
        cart: [...state.cart, { ...action.product, quantity: 1 }],
      };
    }
    case REMOVE_FROM_CART:
      return {
        ...state,
        cart: state.cart.filter((item) => item.id !== action.productId),
      };
    case INCREMENT_QUANTITY: {
      const newCart = state.cart.map((item) =>
        item.id === action.productId
          ? { ...item, quantity: item.quantity + 1 }
          : item
      );
      return { ...state, cart: newCart };
    }
    case DECREMENT_QUANTITY: {
      const newCart = state.cart.map((item) =>
        item.id === action.productId && item.quantity > 1
          ? { ...item, quantity: item.quantity - 1 }
          : item
      );
      return { ...state, cart: newCart };
    }
    default:
      return state;
  }
}

Далее мы реализуем основной компонент, который будет использовать функцию useReducer для управления состоянием корзины. Функция useReducer возвращает текущее состояние и функцию отправки для запуска обновлений состояния:

import React, { useReducer, useContext } from "react";

function MyApp() {
  const [state, dispatch] = useReducer(reducer, initialState);

  const addToCart = (product) => {
    dispatch({ type: ADD_TO_CART, product });
  };

  const removeFromCart = (productId) => {
    dispatch({ type: REMOVE_FROM_CART, productId });
  };

  const incrementQuantity = (productId) => {
    dispatch({ type: INCREMENT_QUANTITY, productId });
  };

  const decrementQuantity = (productId) => {
    dispatch({ type: DECREMENT_QUANTITY, productId });
  };

  const cartValue = {
    cart: state.cart,
    addToCart,
    removeFromCart,
    incrementQuantity,
    decrementQuantity,
  };

  return (
    <CartContext value={cartValue}>
      <div className="container">
        <ProductList />
        <Cart />
      </div>
    </CartContext>
  );
}

В приведенном выше фрагменте кода такие функции, как AddToCart() и removeFromCart(), используют функцию dispatch() для запуска действий, а компоненты <CartContext /> обертывают компоненты <ProductList /> и <Cart />, чтобы они могли использовать значения контекста для чтения и обновления состояния корзины.

Создайте компоненты <ProductList /> и <Cart />, как показано в приведенном ниже фрагменте:

function ProductList() {
  const products = [
    { id: 1, name: "Product 1", price: 29.99 },
    { id: 2, name: "Product 2", price: 49.99 },
    { id: 3, name: "Product 3", price: 19.99 },
  ];

  const { addToCart } = useContext(CartContext);

  return (
    <div>
      <h2>Product List</h2>
      <ul>
        {products.map((product) => (
          <li key={product.id}>
            {product.name} - ${product.price.toFixed(2)}
            <button onClick={() => addToCart(product)}>Add to Cart</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

function Cart() {
  const { cart, removeFromCart, incrementQuantity, decrementQuantity } =
    useContext(CartContext);

  return (
    <div>
      <h2>Shopping Cart</h2>
      <ul>
        {cart.map((item) => (
          <li key={item.id}>
            {item.name} - ${item.price.toFixed(2)} x {item.quantity}
            <span className="cart-buttons">
              <button onClick={() => decrementQuantity(item.id)}>-</button>
              <button onClick={() => incrementQuantity(item.id)}>+</button>
              <button onClick={() => removeFromCart(item.id)}>Remove</button>
            </span>
          </li>
        ))}
      </ul>
    </div>
  );
}

Компонент <ProductList /> отображает товары и позволяет пользователю добавлять их в корзину. Компонент <Cart /> отображает товары в корзине и предоставляет кнопки для изменения количества или удаления товаров.

Такой подход идеально подходит для управления сложной логикой состояния и совместного использования состояния несколькими дочерними компонентами. Он позволяет поддерживать бизнес-логику в чистоте и централизованно, что упрощает обслуживание приложения.

Выбор между useState() и useReducer()

При выборе между useState() и useReducer() вам следует внимательно изучить вариант использования вашего приложения и логику состояния.

Например, useState() отлично работает при работе с независимыми элементами состояния, такими как переключение переключателя или диалогового окна, управление вводом данных в форму и т.д.

С другой стороны, использование useReducer() предпочтительнее, когда у вас сложная логика состояния, в которой новое состояние зависит от значения предыдущего состояния. Это централизует логику обновления состояния в единую функцию, как мы видели в примере с корзиной покупок. Если управление состоянием вашего компонента с помощью useState() начинает усложняться, это хороший знак для того, чтобы рассмотреть возможность перехода на useReducer() для более организованного подхода.

Вы можете ознакомиться с рабочей демонстрацией здесь.

Повышение производительности

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

Давайте рассмотрим, как оптимизировать контекст React на примере простого приложения для управления задачами:

import React, { useState, useContext, useEffect } from "react";

const TaskContext = React.createContext();

function TaskProvider({ children }) {
  const [tasks, setTasks] = useState([
    { id: 1, text: "Design homepage", completed: false },
    { id: 2, text: "Develop backend", completed: false },
  ]);

  const addTask = (taskText) => {
    setTasks((prevTasks) => [
      ...prevTasks,
      { id: Date.now(), text: taskText, completed: false },
    ]);
  };

  const toggleTaskCompletion = (taskId) => {
    setTasks((prevTasks) =>
      prevTasks.map((task) =>
        task.id === taskId ? { ...task, completed: !task.completed } : task
      )
    );
  };

  const contextValue = {
    tasks,
    addTask,
    toggleTaskCompletion,
  };

  return (
    <TaskContext value={contextValue}>{children}</TaskContext>
  );
}

function TaskList() {
  const { tasks, toggleTaskCompletion } = useContext(TaskContext);

  return (
    <div>
      <h2>Task List</h2>
      <ul>
        {tasks.map((task) => (
          <li key={task.id}>
            <span
              style={{
                textDecoration: task.completed ? "line-through" : "none",
              }}
            >
              {task.text}
            </span>
            <button onClick={() => toggleTaskCompletion(task.id)}>
              {task.completed ? "Undo" : "Complete"}
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

function AddTask() {
  const { addTask } = useContext(TaskContext);

  useEffect(() => {
    console.log(`<AddTask />`);
  });

  const handleAddTask = () => {
    const taskText = prompt("Enter task description:");
    if (taskText) {
      addTask(taskText);
    }
  };

  return (
    <div>
      <h2>Add New Task</h2>
      <button onClick={handleAddTask}>Add Task</button>
    </div>
  );
}

function App() {
  return (
    <TaskProvider>
      <TaskList />
      <AddTask />
    </TaskProvider>
  );
}

export default App;

В приведенном выше коде у нас есть TaskContext, который содержит элементы задачи и функцию AddTask(). Хотя это и просто, у этого есть недостаток: каждый раз, когда элемент добавляется или завершается, значение контекста меняется. Кроме того, изменяются все компоненты, использующие TaskContext. Это включает в себя компонент <AddTask />, который занимается только добавлением элементов, а не их отображением.

Это происходит потому, что значение контекста является объектом, что означает, что оно будет воссоздаваться при каждом рендеринге. Таким образом, React считает, что значение контекста изменилось.

Итак, как нам это оптимизировать? Мы должны разделить контекст на два: один для элементов задачи, а другой для действий над задачей. Разделяя состояния и действия на разные контексты, мы гарантируем, что компоненты реагируют только на те данные, которые им нужны. Например, <TaskList /> заботится только об элементах задачи, в то время как <AddTask /> нужно только знать, как добавить новую задачу:

const TaskContext = React.createContext();
const TaskActionContext = React.createContext();

function TaskProvider({ children }) {
  const [tasks, setTasks] = useState([
    { id: 1, text: "Design homepage", completed: false },
    { id: 2, text: "Develop backend", completed: false },
  ]);

  const taskStateValue = {
    tasks,
  };

  const addTask = useCallback((taskText) => {
    setTasks((prevTasks) => [
      ...prevTasks,
      { id: Date.now(), text: taskText, completed: false },
    ]);
  }, []);

  const toggleTaskCompletion = useCallback((taskId) => {
    setTasks((prevTasks) =>
      prevTasks.map((task) =>
        task.id === taskId ? { ...task, completed: !task.completed } : task
      )
    );
  }, []);

  const taskActionValue = useMemo(
    () => ({
      addTask,
      toggleTaskCompletion,
    }),
    [addTask, toggleTaskCompletion]
  );

  return (
    <TaskContext value={taskStateValue}>
      <TaskActionContext value={taskActionValue}>{children}</TaskActionContext>
    </TaskContext>
  );
}

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

Это не только повышает производительность, но и делает приложение более предсказуемым и простым в обслуживании. При переключении задачи обновляется только <Список задач />, а не <Добавить задачу />, потому что мы четко определили, о чем заботится каждый компонент.

Сравнение с контекстом React

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

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

Заменяет ли Redux контекст React? Короткий ответ - нет, это не так. Context и Redux - это два разных инструмента, и сравнение часто возникает из-за неправильного представления о том, для чего предназначен каждый инструмент. Хотя контекст можно настроить так, чтобы он действовал как инструмент управления состоянием, он не был разработан для этой цели, поэтому вам придется приложить дополнительные усилия, чтобы заставить его работать. Уже существует множество инструментов управления состоянием, которые хорошо работают и облегчат ваши проблемы.

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

По моему опыту работы с Redux, добиться чего-то, что сегодня проще решить с помощью Context, может быть относительно сложно. Имейте в виду, что пути Redux и Context пересекаются в процессе детализации и глобального управления состоянием. Redux обладает большей функциональностью в этой области. В конечном счете, Redux и Context следует рассматривать как взаимодополняющие инструменты, которые работают вместе, а не как альтернативы. Я рекомендую использовать Redux для комплексного глобального управления состоянием, а Context - для бурения скважин.

Вывод

В этой статье мы рассмотрели, что такое React Context, когда мы должны использовать его, чтобы избежать повторной проверки, примеры его использования и как мы можем использовать контекст наиболее эффективно. Мы также прояснили некоторые заблуждения, связанные с React Context и Redux.

Основные выводы из этой статьи включают следующее:

  • Контекстный API React предназначен для бурения с использованием пропеллеров
  • Если вы используете контекст для глобального управления состоянием, используйте его с осторожностью
  • Если вы не можете быть осмотрительны с контекстом, попробуйте Redux
  • Redux можно использовать независимо от React
  • Redux - не единственный доступный инструмент управления состоянием

Я надеюсь, вам понравился этот урок!