53
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

リロードしてもデータを保持するためには「localStorage」

アプリを作った時悲しかったこと

プログラミングで初めて自分で作ったアプリ。Todoアプリなんかを駆け出しエンジニアの方々は作ったことだろう。
私もその一人です。
初めて自分で開発したアプリ、感動ものですよね。

完成したアプリの動作を確認します。
入力フォームにデータを入力して、保存ボタンを押して、データを表示させる。。。。
うまくいった!その時の嬉しさはなんとも言えないものがあります。

そして、ページをリロードっ!!!!
・・・・データが消えてる、、ページをリロードすると、、、データが消えてしまう。悲しい。

localStorageメソッド

そんな駆け出しエンジニアの悩みを解決するメソッドがあります。
「localstorage」メソッドです。

追記:localStrage APIのセキュリティ上の問題点について興味深い記事があったので、一読ください。実際にアプリケーションを公開する場合は機密情報の保持等に気をつけて当APIを活用するのが好ましいと思われます。
https://techracho.bpsinc.jp/hachi8833/2019_10_09/80851

MDN -Window.localStorage-

MDNの例文をconsole等で簡単に試して見ましょう。

ローカルのStorageオブジェクトにアクセスし、setItem()で値を追加します。

localStorage.setItem('myCat', 'Tom');

getItem()で値を取得します

var cat = localStorage.getItem("myCat");
console.log(cat)
//出力結果 > "Tom"

では、command + Rでページをリロードしてみましょう。
もう一度データを取得します。

var cat = localStorage.getItem("myCat");
console.log(cat)
// 出力結果 > "Tom"

ページをリロードしても、データが取得できていることがわかります。

少し実践

Reactでこのメソッドを使って、データを保持できるようにして見たいと思います。

src/App.js
import React, { useEffect, useReducer } from 'react'

//省略

const APP_KEY = 'sampleApp'

const App = () => {
  const appState = localStorage.getItem(APP_KEY)
  const initialState = appState ? JSON.parse(appState) : {
    events: [],
    operationLogs: []
  }
  const [state, dispatch] = useReducer(reducer, initialState)

  useEffect(() => {
    localStorage.setItem(APP_KEY, JSON.stringify(state))
  }, [state])

  return (
    {/* ---------------------------

       ここに表示させたいフォーマットを書く

     ----------------------------------     */}

  )
}

export default App

上記のコードが何をしているのか解説します。
メソッドについて確認しておきましょう。
まずは、JSONを扱うメソッドについてです。

JSON.parse()
受け取った文字列をJSONに変換し、JavaScriptの値やオブジェクトを構築することができる

JSON.stringify
与えられたJavaScript の値を JSON 文字列に変換するメソッド

MDN -JSON-

以上のメソッドを理解したうえで、上記のコードを分解して見ていきましょう。

const APP_KEY = 'sampleApp'

const App = () => {
  const appState = localStorage.getItem(APP_KEY)
  const initialState = appState ? JSON.parse(appState) : {
    events: []
  }

localStorage.getItem()を使って、ローカルStorageをリロードされた際に取得しています。値があるかどうかを三項演算子で判定していますが、もちろん、何もデータが格納されていない際には、initialStateには何も値が渡されないので、eventsオブジェクトには空配列が渡されます。

では、次です。

const [state, dispatch] = useReducer(reducer, initialState)

  useEffect(() => {
    localStorage.setItem(APP_KEY, JSON.stringify(state))
  }, [state])

useReducerを用いて、値を保持しています。ここでは、フォーマットになんらかの値が入力され、値がreducerから返ってきたと仮定しましょう。

useEffectは第二引数に配列を渡すことができるので受け取ったstateをこのように格納して、保持することができます。

localStorage.setItem()を用いて、ローカルStorageにデータを追加します。データを表示するためにJSON.stringify()メソッドを用いて、文字列に変化させていることにも注目してください。

それでは、また冒頭のコードに戻って見ましょう。

const APP_KEY = 'sampleApp'

const App = () => {
  const appState = localStorage.getItem(APP_KEY)
  const initialState = appState ? JSON.parse(appState) : {
    events: []
  }

今度はローカルStrageに値があると仮定しているので、
localStorage.getItem()メソッドで値を取得できていることがわかります。
なので、initialStateの結果もtrueとなります。返り値はオブジェクトではなければならないので、JSON.parseを用いて、先ほど文字列に変換した値をまたオブジェクトに変換していることにも注目してください。

これで、リロードをしても値が保持できるようになると思います。

まとめ

MDN -Web Storage API を使用する-
localStprageメソッドについて詳しく知りたい方は上記のリンクを参照してください。
今回はReactで作ったアプリを用いて解説してみましたが、ぜひ色々試して見てください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
53
Help us understand the problem. What are the problem?