Как сохранять состояние между маршрутами в React
Используем глобальное состояние через Context API
Context API — это встроенный инструмент React, который позволяет сохранять данные в одном месте и делиться ими между компонентами.
- Сначала создается контекст с помощью функции createContext. Это что-то вроде "хранилища", которое мы будем использовать в приложении.
- Затем мы оборачиваем наше приложение в провайдер контекста. Провайдер принимает значение, которое будет доступно всем компонентам внутри.
- Наконец, в нужных компонентах мы получаем данные из контекста с помощью функции 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 — это не только адрес страницы, но и место для хранения данных.
- Чтобы передать состояние, вы можете добавить параметры в URL. Например, маршрут /page2?value=123 может содержать данные о текущем состоянии.
- Чтобы получить эти данные на новой странице, используйте хук useSearchParams из библиотеки React Router.
- Для работы с состоянием на странице лучше комбинировать параметры 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 — это библиотека для управления состоянием, которая позволяет централизованно хранить данные.
- Сначала создается "хранилище" с помощью функции createStore и корневого редьюсера. Редьюсер — это функция, которая обновляет состояние на основе переданных действий.
- Затем приложение оборачивается в компонент Provider из библиотеки react-redux, который делает хранилище доступным всем компонентам.
- Наконец, с помощью хуков 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 идеально подходит для масштабных приложений, где важно предсказуемое поведение состояния и его легкий доступ из любого компонента.






Комментарии