Hooksまとめ
Hooksまとめ
- useState
- useEffect
- useContext
- useRef
- useReducer
準備
$ npm create vite@latest
reactを選択
$ . code
VSCODEが立ちあがる
$ npm run dev
実行
useState
状態の変化が起こったときにレンダリングを行う
Reactは仮想DOMの差分だけを見ており、差分が発生したら変更点だけ
リアルDOMに反映する
export const App = () => {
const [count, setCount] = useState(0)
const handleClick = () => {
setCount(count + 1);
}
return (
<div className="App">
<h1>UseState</h1>
<p>状態の変化が起こったときにレンダリングを行う</p>
<button onClick={handleClick} >+</button>
<p>{count}</p>
</div>
)
useEffect
発火のタイミングを指定する
useEffect(コールバック関数,配列)
- 配列が空だとコンポーネントのマウント時に一回呼ばれる
- []の中に変数を入れると、入れた変数が変更された時に発火する
ではこのような場合は…?
useEffect(() => {
console.log("Hello Hooks");
setCount(count + 1);
}, [count])
えらいことになる。setCountがcountを変更してさらにuseEffectが呼ばれて、無限ループが発生するので気を付けよう。
useContext
staticグローバル変数みたいなやつ
まずは全体で使いたいデータを用意しよう
const myInfo = {
name: "dollaga",
age: 30,
}
そしてcreateContextでContextを用意します
export const MyInfoContext = createContext(myInfo);
最後にProviderを使い全体を囲む
ReactDOM.createRoot(document.getElementById('root')).render(
<MyInfoContext.Provider value={myInfo}>
<React.StrictMode>
<App />
</React.StrictMode>
</MyInfoContext.Provider>
)
使いたい要素をpropsのvalueで渡す必要があるらしい
では使う側はどうか?
export const App = () => {
const [count, setCount] = useState(0)
const myInfo = useContext(MyInfoContext)
~
return (
<div className="App">
<h1>useContext</h1>
<p>staticグローバル変数みたいなやつ</p>
<p>{myInfo.name}</p>
<p>{myInfo.age}</p>
</div>
)
というわけでmain.jsxで定義したMyInfoをAppに直接渡すことができました
どんな場合に必要か?
ユーザーのログイン情報などどのページでも使う情報
useRef
指定したhtmlのタグを参照する(reference)
const ref = useRef();
const handleRef = () => {
console.log(ref);
}
~
return (
<div className="App">
<h1>useRef</h1>
<input type="text" ref={ref} />
<button onClick={handleRef}>UseRef</button>
</div>
)
こうしてボタンを押すと、様々なinputタグの情報をみることが出来る
valueの中身を見たい時などに活用できる
const handleRef = () => {
console.log(ref.current.value); //valueの中身
}
useReducer
あんまり使わない??
考え方が難しい割には使わなくても実現できるなあ
const reducer = (state, action) => {
switch (action.type) {
case "increment":
return state + 1;
case "decrement":
return state - 1;
default:
return state;
}
};
~
const [state, dispatch] = useReducer(reducer, 0);
~
<h1>useReducer</h1>
<p>カウント:{state}</p>
<button onClick={() => dispatch({type: "increment"})}>+</button>
<button onClick={() => dispatch({type: "decrement"})}>-</button>
useMemo
パフォーマンスをチューニングするためのHooks
ブラウザのメモリに保存=メモ化
重い処理の時に使うけど、どんなものが重い処理か定義できないので、
開発しながら考えよう
つまり、最初からは使えない...かもしれない(shincodeさん曰く)
なんでもかんでも使えばいいかというと、そういうわけでもない
(メモリリークしちゃう)
useCallback
callback関数のメモ化
useMemoと使い方は同じ
つまり、あんまり使わないらしい笑
ちょっと検討の価値があるなあ
カスタムフック
今回はローカルストレージに年齢を保存するHooksだぞ
これを参考にいろいろ作れそうだな
import React, { useEffect, useState } from 'react'
export const useLocalStorage = (key, defaultValue) => {
const [value, setValue] = useState(() => {
const jsonValue = window.localStorage.getItem(key);
if(jsonValue !== null) return JSON.parse(jsonValue);
return defaultValue
})
useEffect(() => {
window.localStorage.setItem(key, JSON.stringify(value))
}, [value, setValue]);
return [value, setValue];
}