Как сохранить состояние между обновлениями страницы в React
Здравствуйте, дорогой читатель!
В этой статье я хотел бы показать вам, как сохранять состояние между обновлениями страниц в React. Проверьте это в действии:
Подобная вещь называется сохранением состояния и позволяет вам сохранять состояние нетронутым даже при обновлении страницы или закрытии браузера.
Сохранение состояния имеет множество вариантов использования. Например, вы можете захотеть, чтобы заполненные поля в форме оставались даже после того, как пользователь покинул страницу, а затем вернулся позже.
Сделать состояние постоянным на самом деле довольно легко. Для этого мы будем использовать локальное хранилище.
В этом проекте будет использоваться TypeScript, но вы также можете использовать JavaScript, и в этом случае просто опустите типы.
Итак, без лишних слов, приступим!
Структура проекта
Мы создадим хук под названием usePersistState(), который будет использоваться так же, как обычный хук состояния, с дополнительным бонусом в виде постоянства.
В этой статье предполагается, что вы уже знаете, как настроить проект, поэтому я пропущу эту часть. Для настройки проекта вы можете использовать любой инструмент, такой как CRA, Vite, NextJS и т. д.
Структура нашего проекта будет выглядеть так
- index.tsx — страница, на которой мы будем тестировать наш хук
- usePersistState.ts — файл, в котором мы будем держать наш хук
Итак, теперь, когда мы определили структуру нашего проекта, мы можем приступить к кодированию!
usePresistState.ts
Прежде всего, давайте создадим нашу функцию-перехватчик:
export default function usePersistState<T>(initial_value: T, id: string): [T, (new_state: T) => void] {
}
Итак, мы объявили функцию usePersistState
, которая имеет общий тип T
. В качестве аргументов вы можете указать начальное значение состояния, а также уникальный идентификатор для идентификации нашего состояния в локальном хранилище. Наконец, мы указываем тип возвращаемого значения как массив, содержащий состояние и функцию установки состояния (точно так же, как обычный useState())
.
Далее давайте создадим новую переменную _initial_state
, которая будет определять, использовать ли значение из локального хранилища или значение, переданное в перехватчик.
// Set initial value
const _initial_value = useMemo(() => {
const local_storage_value_str = localStorage.getItem('state:' + id);
// If there is a value stored in localStorage, use that
if(local_storage_value_str) {
return JSON.parse(local_storage_value_str);
}
// Otherwise use initial_value that was passed to the function
return initial_value;
}, []);
Здесь мы проверяем, есть ли в localStorage
уже сохраненный элемент для нашего состояния. Если да, то мы используем значение localStorage
для нашего начального состояния. В противном случае мы используем начальное значение, которое было передано в качестве аргумента нашему хуку. Мы обертываем это в useMemo
, чтобы _initial_value
устанавливалось только один раз, при монтировании (потому что оно нам нужно только при монтировании).
Далее давайте добавим само состояние, которое использует _initial_value
, которое мы определили в предыдущем фрагменте кода.
const [state, setState] = useState(_initial_value);
Теперь давайте добавим useEffect
, который запускается каждый раз, когда наше состояние изменяется, чтобы сохранить состояние в локальном хранилище:
useEffect(() => {
const state_str = JSON.stringify(state); // Stringified state
localStorage.setItem('state:' + id, state_str) // Set stringified state as item in localStorage
}, [state]);
Это просто означает, что всякий раз, когда наше состояние изменяется, значение состояния сохраняется в localStorage
.
Наконец, давайте вернем наше состояние и вызовем setState()
.
return [state, setState];
Иаа, мы закончили! Наш крючок готов, теперь можно его проверить!
index.tsx
В index.tsx
вставьте следующий код:
import { usePersistState } from '@printy/react-persist-state/src/index';
import React from 'react'
export default function PersistStateExample() {
const [counter, setCounter] = usePersistState(0, 'counter');
return (
<div>
<button
onClick={() => setCounter(counter + 1)}
>
{counter}
</button>
</div>
)
}
Здесь мы создаем counter
счетчика, используя наш новый крючок и кнопку, которая показывает значение counter
, а также увеличивает счетчик при каждом нажатии на нее. Попробуйте нажать на него несколько раз, а затем обновить страницу. Вы увидите, что состояние сохранилось. Вы даже можете полностью закрыть браузер и повторно загрузить страницу, а состояние останется!
Заключение
В этой статье мы узнали, как создать постоянное состояние в React, которое не сбрасывается при обновлении страницы. Надеюсь, эта статья была вам полезна и вы найдете способ использовать этот метод.
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии ниже!
Спасибо за чтение, и хорошего дня!