Как сохранять состояние между маршрутами в React

На список статей
Blog image

Track My Time — Управляй временем эффективно и достигай большего!
"Ваш незаменимый помощник в управлении проектами и учете времени! Отслеживайте задачи, распределяйте ресурсы и контролируйте каждую минуту работы. Повышайте эффективность, упрощайте процессы и достигайте результатов быстрее. Начните работать с нами и добейтесь успеха вместе!"

Используем глобальное состояние через Context API

Context API — это встроенный инструмент React, который позволяет сохранять данные в одном месте и делиться ими между компонентами.

  1. Сначала создается контекст с помощью функции createContext. Это что-то вроде "хранилища", которое мы будем использовать в приложении.
  2. Затем мы оборачиваем наше приложение в провайдер контекста. Провайдер принимает значение, которое будет доступно всем компонентам внутри.
  3. Наконец, в нужных компонентах мы получаем данные из контекста с помощью функции useContext.
import React, { createContext, useState, useContext } from 'react';

// Создаем контекст
const AppContext = createContext();

function AppProvider({ children }) {
 const [state, setState] = useState("Начальное значение");

 return (
   <AppContext.Provider value={{ state, setState }}>
     {children}
   </AppContext.Provider>
 );
}

function Page1() {
 const { state, setState } = useContext(AppContext);
 return (
   <div>
     <h1>Страница 1</h1>
     <p>Текущее состояние: {state}</p>
     <button onClick={() => setState("Новое значение")}>Изменить состояние</button>
   </div>
 );
}

function Page2() {
 const { state } = useContext(AppContext);
 return (
   <div>
     <h1>Страница 2</h1>
     <p>Текущее состояние: {state}</p>
   </div>
 );
}

export default function App() {
 return (
   <AppProvider>
     <Page1 />
     <Page2 />
   </AppProvider>
 );
}

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

Используем URL параметры и локальное состояние

URL — это не только адрес страницы, но и место для хранения данных.

  1. Чтобы передать состояние, вы можете добавить параметры в URL. Например, маршрут /page2?value=123 может содержать данные о текущем состоянии.
  2. Чтобы получить эти данные на новой странице, используйте хук useSearchParams из библиотеки React Router.
  3. Для работы с состоянием на странице лучше комбинировать параметры URL с локальным состоянием.
import React, { useState, useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';

function Page1({ navigate }) {
 const [inputValue, setInputValue] = useState("");

 const handleNavigate = () => {
   navigate(`/page2?value=${inputValue}`);
 };

 return (
   <div>
     <h1>Страница 1</h1>
     <input
       type="text"
       value={inputValue}
       onChange={(e) => setInputValue(e.target.value)}
     />
     <button onClick={handleNavigate}>Перейти на Страницу 2</button>
   </div>
 );
}

function Page2() {
 const [searchParams] = useSearchParams();
 const [state, setState] = useState("");

 useEffect(() => {
   setState(searchParams.get("value") || "Нет данных");
 }, [searchParams]);

 return (
   <div>
     <h1>Страница 2</h1>
     <p>Полученное состояние: {state}</p>
   </div>
 );
}

Этот подход подходит, если состояние небольшое и может быть закодировано в строке. Однако для сложных объектов это может стать неудобным.

Используем Redux для сложных приложений

Redux — это библиотека для управления состоянием, которая позволяет централизованно хранить данные.

  1. Сначала создается "хранилище" с помощью функции createStore и корневого редьюсера. Редьюсер — это функция, которая обновляет состояние на основе переданных действий.
  2. Затем приложение оборачивается в компонент Provider из библиотеки react-redux, который делает хранилище доступным всем компонентам.
  3. Наконец, с помощью хуков useSelector и useDispatch компоненты могут получать состояние из хранилища и отправлять действия для его изменения.
import React from 'react';
import { createStore } from 'redux';
import { Provider, useSelector, useDispatch } from 'react-redux';

// Редьюсер
function appReducer(state = { value: "Начальное состояние" }, action) {
 switch (action.type) {
   case "SET_VALUE":
     return { ...state, value: action.payload };
   default:
     return state;
 }
}

// Создаем хранилище
const store = createStore(appReducer);

function Page1() {
 const dispatch = useDispatch();
 const handleChangeState = () => {
   dispatch({ type: "SET_VALUE", payload: "Новое состояние" });
 };

 return (
   <div>
     <h1>Страница 1</h1>
     <button onClick={handleChangeState}>Изменить состояние</button>
   </div>
 );
}

function Page2() {
 const value = useSelector((state) => state.value);
 return (
   <div>
     <h1>Страница 2</h1>
     <p>Состояние из Redux: {value}</p>
   </div>
 );
}

export default function App() {
 return (
   <Provider store={store}>
     <Page1 />
     <Page2 />
   </Provider>
 );
}

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

Комментарии

Пока нет комментариев

Добавить комментарий