React 状態維持方法解説
React.js でページリフレッシュ後の状態を維持する方法
React.js では、ページリフレッシュ後に状態を維持するために、主に localStorage や sessionStorage を活用します。
localStorage と sessionStorage の違い
- sessionStorage
ブラウザのセッション中にのみデータを保存します。ブラウザを閉じるとデータは失われます。 - localStorage
ブラウザのセッションを超えてデータを保存します。つまり、ブラウザを閉じて再度開いてもデータが保持されます。
localStorage を使用した例
import React, { useState, useEffect } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
const storedCount = localStorage.getItem('count');
if (storedCount) {
setCount(parseInt(storedCount));
}
}, []);
useEffect(() => {
localStorage.setItem('count', count);
}, [count ]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
この例では、useEffect
フックを使用して、count
の状態を localStorage
に保存し、ページリフレッシュ時に localStorage
から復元しています。
sessionStorage を使用した例
import React, { useState, useEffect } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
con st storedCount = sessionStorage.getItem('count');
if (storedCount) {
setCount(parseInt(storedCount));
}
}, []);
useEffect(() => {
sessionStorage.setItem('count', count);
}, [count]);
// ...
}
sessionStorage の使用方法は localStorage とほぼ同じです。ただし、データの保存期間がブラウザセッション中に限られます。
注意事項
- データのサイズ
localStorage
とsessionStorage
の容量には制限があります。大量のデータを保存する場合は、サーバーサイドストレージやデータベースを使用することを検討してください。 - データのセキュリティ
localStorage
やsessionStorage
に保存するデータは、ブラウザの開発者ツールを使用して閲覧することができます。機密情報については、適切な暗号化やサーバーサイドでの保存を検討してください。
import React, { useState, useEffect } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
const storedCount = localStorage.getItem('count');
if (storedCount) {
setCount(parseInt(storedCount));
}
}, []);
useEffect(() => {
localStorage.setItem('count', count);
}, [count ]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
解説
useState
フックを使用して、count
という状態変数を初期化します。- 第1の
useEffect
フックは、コンポーネントが最初にマウントされたときに実行されます。localStorage
からcount
の値を取得します。- 取得した値が存在する場合、
count
の状態を更新します。
- 第2の
useEffect
フックは、count
の状態が変更されるたびに実行されます。count
の値をlocalStorage
に保存します。
import React, { useState, useEffect } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
con st storedCount = sessionStorage.getItem('count');
if (storedCount) {
setCount(parseInt(storedCount));
}
}, []);
useEffect(() => {
sessionStorage.setItem('count', count);
}, [count]);
// ...
}
解説
localStorage
との違いは、sessionStorage
を使用している点です。sessionStorage
はブラウザのセッション中にのみデータを保存します。
重要なポイント
URLパラメータを利用する
- 欠点
URLが長くなる可能性があり、複雑な状態を表現するには不向き。 - 利点
シンプルで直感的。
import { useLocation, useNavigate } from 'react-router-dom';
function MyComponent() {
const location = useLocation();
const navigate = useNavigate ();
const count = parseInt(location.search.split('=')[1]) || 0;
const increment = () => {
navigate(`?count=${count + 1}`);
};
return (
// ...
);
}
ReduxやContext APIを利用する
- 欠点
学習コストが高く、プロジェクトの規模によってはオーバーエンジニアリングになる可能性がある。 - 利点
グローバルな状態管理が可能で、複雑なアプリケーションにも適している。
Reduxの例
import { createStore } from 'redux';
import { Provider, useSelector, useDispatch } from 'react-redux';
// Reducer
const reducer = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1;
default:
return state;
}
};
// Store
const store = createStore(reduc er);
// Component
function MyComponent() {
const count = useSelector(state => state);
const dispatch = useDispatch();
const increment = () => {
dispatch({ type: 'INCREMENT' });
};
return (
// ...
);
}
// App
function App() {
return (
<Provider store={store}>
<MyComponent />
</Provider>
);
}
Context APIの例
import React, { createContext, useContext, useState } from 'react';
const CountContext = createContext();
function CountProvider({ children }) {
const [count, setCount] = useState(0);
return (
<CountContext.Provider value={{ count, increment: () => setCount(count + 1) }}>
{children}
</CountContext.Provider>
);
}
function MyComponent() {
const { count, increment } = useContext(CountContext);
return (
// ...
);
}
カスタムフックを利用する
- 欠点
複雑な状態管理には不向きな場合がある。 - 利点
再利用性が高く、コードを整理しやすい。
import { useState, useEffect } from 'react';
function useLocalStorageState(key, defaultValue) {
const [state, setState] = useState(() => {
const storedValue = localStorage.getItem(key);
return st oredValue || defaultValue;
});
useEffect(() => {
localStorage.setItem(key, state);
}, [key, state]);
return [state, setState];
}
function MyComponent() {
const [count, setCount] = useLocalStorageState('count', 0);
return (
// ...
);
}
javascript reactjs