なぜResact useCallbackを使うのか


なぜreact memoを使うのですか?の記事から始まります.
なぜButton構成部品のみを再実行するのですか?これはParagraph素子のpropsが元のタイプのfalseを伝達し,Button素子のpropsが関数を伝達するためである.
コンポーネントの再実行を適用するたびに、新しいtoggleParagraphHandler関数が作成されます.関数の内容は同じであることは明らかですが、JavaScriptの関数がオブジェクトであるため、Buttonコンポーネントはpropsが変更されたと判断し、コンポーネントを再実行します.
(オブジェクトは値を格納するのではなく値を格納します.オブジェクトの格納値のアドレスはメモリに格納されている値と同じなので、一致演算子と比較してもfalseが出力されます)

この場合、useCallbackで関数をラップするとreactは関数を保存し、2番目のパラメータdependenciesが変わらなければ関数は再生しないので、この関数をpropsのサブコンピューティング素子として関数が置き換えられたとは思わない.
したがって,サブコンポーネントのprops伝達の関数としてuseCallbackを用いることで再実行回数を減らすことができ,より効率的なアプリケーションを作成することができる.
// App.js
import { Fragment, useState } from 'react';

import Button from './components/Button';
import Paragraph from './components/Paragraph';

function App() {
  console.log('App Running');

  const [showParagraph, setShowParagraph] = useState(false);

  const toggleParagraphHandler = useCallback(() => {
    setShowParagraph((prevState) => !prevState);
  }, []);

  return (
    <Fragment>
      <Paragraph show={false} />
      <Button onChangeText={toggleParagraphHandler} />
    </Fragment>
  );
}

export default App;
// Paragraph.js
import react from 'react';

const Paragraph = (props) => {
  console.log('Paragraph Running');

  return <p>{props.show ? 'HELLO' : ''}</p>;
};

export default react.memo(Paragraph);
// Button.js
import react from 'react';

const Button = (props) => {
  console.log('Button Running');

  return <button onClick={props.onChangeText}>Change Text!</button>;
};

export default react.memo(Button);

useCallbackで包むと、Button構成部品も再稼働しないことがわかります.