useCallbackはどこで使えばいいのか?使い所とは

useCallbackはどこで使えばいいのか?使い所とは

LINEで送る
Pocket

hooksAPIの中で、useCallbackの使い所がいまいちわからなかったので検証してみました。

 

結果だけ知りたい人

自コンポーネントだけで使うコールバック関数の場合は使う必要なし。

コールバック関数を渡す子コンポーネントでmemo化などをしてない限り使う必要なし。

 

検証

実際に検証してみました。

まずは、useCallbackを使わないパターンです

フォームに値を入れたり、UPを押したりしてレンダリングを確認してみます。

親コンポーネント

export default function CounterApp () {
  const [counter, setCounter] =React.useState(0)
  const [value, setValue] =React.useState("")

  const handleIncrement=()=> {
    setCounter(state=>state+1)
  }
  
  // useCallbackを使ったもの
  // const handleIncrement=React.useCallback(()=> { setCounter(state=>state+1) }, [setCounter])
  
  console.log("render counterApp")
  return (
    <div>
      <h1>Counter</h1>
      <input value={value} onChange={(e)=>setValue(e.target.value)}/>
      <div>{counter}</div>
      <Wrapper increment={handleIncrement}/>
    </div>
  )
}

 

インクリメントするだけのボタンコンポーネント

メモ化しているのでpropsに変更がなければ再レンダーされません。

const Counter: React.FC<{increment: () => void}> = React.memo((props) =>{
  console.log("render counter")
  return (
    <div>
      <button onClick={props.increment}>UP</button>
    </div>
  )
})

 

Counterコンポーネントをラップするコンポーネント

const Wrapper: React.FC<{increment: () => void}> = (props) => {
  console.log("render wrapper")
  return<Counter increment={props.increment}/>
}

 

このコンポーネントのフォームに値を入れると…

memo化したcounterコンポーネントもレンダリングされてしまっています。

 

次にuseCallbackを使ったインクレメント関数を渡してみます。

CounterAppコンポーネントの関数をuseCallbackにします。

const handleIncrement = React.useCallback(() => {
  setCounter(state=>state+1)
},[setCounter])

これでフォームに値を入れてみると…

うまくいきました。

メモ化されてるcounterコンポーネントのレンダリングがされていません。

LINEで送る
Pocket

フロントエンド開発でお困りのことはありませんか?

フロントエンドの開発支援を行っています。

・Reactの開発をお願いしたい

・コーディング作業を依頼したい

・javascriptライブラリを作って欲しい。

上記以外にも何かありましたらお気軽にお問い合わせください。

コメントを残す