Подписывайтесь на мой твиттер, там всегда что-нибудь интересное!

Используем localStorage в React

Как использовать преимущества localStorage в React? Да легко! В этой статье вы узнаете об удобстве применения локального хранилища в React приложениях.

Перевод How to use localStorage with React

Сердцем каждого приложения на React является его стейт. Компоненты могут иметь свой собственный внутренний стейт и поверьте мне, несмотря на всю их простоту, вы можете делать с ними много невероятно крутых вещей. Но давайте представим, что вы создаёте приложение и в какой-то момент вам надо локально сохранить данные от пользователя или даже сохранить весь стейт для одного или нескольких других компонентов. И тут, возможно, вам захочется понять, а как же можно использовать localStorage в React приложении? Что же, начнем с того, что setState тут вам уже не помощник, но не переживайте, все будет довольно просто. Читаем дальше.

Если вы не знаете про то, как работает localStorage, то вот отличная статья — Как работать с localStorage в JavaScript

Веб хранилище

Оно создано для того, чтобы хранить данные в браузере и оно потерпело значительное количество позитивных улучшений в сравнении со своим предшественником — кукисами. Сначала оно было как HTML5 API, ну а потом переросло уже в независимую рабочую единицу. Хранилище поддерживается буквально каждым современным браузером и даже некоторыми старичками, например такими как IE8. Веб хранилище реализовано двумя способами: первый — localStorage, постоянное хранилище данных, которое можно сравнить с постоянными кукисами, второе — sessionStorage, хранилище существующее только на время определенной сессии и на определенный период времени. Хоть эта статья и работает с localStorage, но вы также можете применить все описанные методики и на sessionStorage.

Наш компонент для рабочего примера

Итак, нам нужен компонент на котором мы будем все испытывать. Тут я думаю, что страница логина с опцией “Remember me” подойдет идеально. Для простоты и понятности, мы не будем добавлять поле пароля. Давайте посмотрим на метод render():

render() {
  return (
    <form onSubmit={this.handleFormSubmit}>
      <label>
        User: <input name="user" value={this.state.user} onChange={this.handleChange}/>
      </label>
      <label>
        <input name="rememberMe" checked={this.state.rememberMe} onChange={this.handleChange} type="checkbox"/> Remember me
      </label>
      <button type="submit">Sign In</button>
    </form>
  );
}

Как вы видите, это довольно простая форма с двумя инпутами и кнопкой. Код который должен обрабатывать стейт также очень легко понять:

export default class SignIn extends Component {
  state = {
    user: '',
    rememberMe: false
  };
 
  handleChange = (event) => {
    const input = event.target;
    const value = input.type === 'checkbox' ? input.checked : input.value;
 
    this.setState({ [input.name]: value });
  };
 
  handleFormSubmit = () => {};
 
  render() { /*...*/ }
}

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

Если вы заполните инпут для пользователя, а потом кликните на “Remember Me” чекбокс и под конец кликните на кнопку “Sign In”, то вы заметите, что форма снова опустеет:

Это вполне нормальное поведение. Теперь мы должны узнать как же нам использовать localStorage в React и заставить форму работать должным образом.

Шаг 1: Сохраняем данные в localStorage

В нашем примере нужно сохранить две вещи:

Значение опции Remember Me

Имя пользователя, но только в том случае, если кликнули на опцию Remember Me

Для этих значений идеальным местом является метод handleFormSubmit:

handleFormSubmit = () => {
  const { user, rememberMe } = this.state;
  localStorage.setItem('rememberMe', rememberMe);
  localStorage.setItem('user', rememberMe ? user : '');
};

Что же происходит в этом методе?

Сначала мы назначаем две переменные с помощью деструктуризации

Далее, мы вызываем метод localStorage.setItem, чтобы хранить значение опции “Remember Me”.

И под конец мы сохраняем имя пользователя, но только в том случае, когда “Remember Me” выставлено на true.

Вот, что пока что у нас есть:

Итак, полдела сделано. Теперь нам надо получить эти значения для компонента.

Шаг 2: Получаем данные из localStorage

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

Обратите внимание, что вы не можете вызывать setState перед тем, как компонент монтируется, так что, если вы предпочитаете подход с конструктором, то выставьте свойство стейта напрямую. Я же предпочитаю аккуратный подход к коснтуктору, настолько аккуратный насколько это возможно, но это дело предпочтений.

componentDidMount() {
  const rememberMe = localStorage.getItem('rememberMe') === 'true';
  const user = rememberMe ? localStorage.getItem('user') : '';
  this.setState({ user, rememberMe });
}

Теперь давайте углубимся в код:

Первым делом мы получаем значение “Remember me”. Уже обратили внимание, что сравнение идёт со строкой “true”? Это потому что localStorage хранит данные как строки. Таким образом нам надо получить хранящееся значение и запарсить его обратно в логический тип данных, перед его непосредственным использованием. Вы бы также могли использовать JSON.parse, если бы были точно уверены в том, что там всегда будет храниться булево значение в виде строки. Но сейчас это нам не подойдет, так как само значение не выставлено при инициализации страницы.

Далее мы получаем имя пользователя, но только в том случае, если remeberMe имеет значение true.

И под конец мы назначаем эти значения стейту компонента.

И вот она магия!

И ещё советик

Как я говорил выше, localStorage может хранить данные только в виде строк. Если вы имеете дело только с несколькими сохраненными значениями, то это не очень то и большая проблема. Но если вы хотите воспользоваться localStorage на полную катушку в вашем приложении, то я очень советую взять на вооружение библиотеку, которая облегчит сохранение и получение данных, обойдя стороной такие процессы, как парсинг и обращение в строку. В этом деле идеально может подойти проверенная в боях Store.js. Это моя личная рекомендация.

Заключение

В React localStorage очень просто использовать. Просто определите в каких случаях лучше сохранять и получать свои данные. Этот момент будет меняться от компонента к компоненту.

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

Если вам нужна хорошая библиотека для работы со значениями localStorage, то рассмотрите использование Store.js.