「Reactハンズオンラーニング」の感想・備忘録4

「Reactハンズオンラーニング」の感想・備忘録3の続き

フック

7.3 useReducer

  • 以下のchecked => !checkedのように、現在のステート値を受け取って新しいステート値を返す関数をリデューサーと呼ぶ。
const [checked, setChecked] = useState(false)
return (
  <p><input type="checkbox" value={checked} onChange={()=>setChecked(checked => !checked)}>{checked ? "ON" : "OFF"}</p>
);
  • useReducerフックを使うと、ステート更新のロジックを抽象化することができる。
  • useReducerは第1引数にリデューサー、第2引数に初期値を取る。
  • 戻り値の配列は、先頭要素がステート値、2番目の要素がリデューサーを実行(dispatch)するための関数
const [checked, toggle] = useReducer(checked =>!checked, false)
return (
  <p><input type="checkbox" value={checked} onChange={toggle}/>{checked ? "ON" : "OFF"}</p>
);
  • リデューサーは現在のステート値と任意の値の2つを引数に取ることもできる。
const [checked2, toggle2] = useReducer((checked2, num) => {
  console.log(num)
  return !checked2
}, 
return (
    <p><input type="checkbox" value={checked2} onChange={()=> toggle2(777)}/>{checked2 ? "ON2" : "OFF2"}</p>
);

7.3.1 useReducerを使った複雑なステート管理

  • useReducerはオブジェクトをステートとして扱う場合に効力を発揮する。
  • 以下の例では、useStateを使った場合だと誤ってsetUser({name: 'hogehoge'})とするとオブジェクトが上書きされてしまう。
  • setUser({...user, name: 'hogehoge'})とすれば問題ないのだが、useReducerを使った方がバグを産む可能性を下げることができる。
  • 個人開発ではuseStateだけでも問題なく、複数人で開発する場合はuseReducerを使うべき、という意見もある。
function Reducer2() {
  const initUser = {
    id: 1,
    name: 'hoge',
  }
  const [user, setUser] = useReducer((user, newValues) => ({...user, ...newValues}), initUser)
  return (
    <div>
      {user.id}: {user.name}
      <button onClick={()=>setUser({name: 'hogehoge'})}>setUser</button>
    </div>
  );
}

7.4 コンポーネントのパフォーマンス改善

  • memo関数は関数コンポーネントをメモ化するためのトップレベル関数である。
  • 以下のようにmemo関数を使うだけで、親コンポーネントが再描画されても、自身は再描画されなくなる。
import {memo} from 'react'
function Memo({msg}) {
  console.log("rendering Memo")
  return (
    <div style={{border: "1px solid #ccc", padding: "50px"}}>
      <h2>Mmeo.js</h2>
      <p>{msg}</p>
    </div>
  );
}

export default memo(Memo);

7.4.1 いつパフォーマンスチューニングを行うか

  • memo関数、useMemoフック、useCallbackフックは乱用される傾向がある。
  • Reactはパフォーマンスが落ちないように設計されているので、まずはこれらを使わずに実装し、パフォーマンスに問題のあるコンポーネントのみこれらを使うべきである。

コメント

タイトルとURLをコピーしました