useCallback VS useMemo

王林
王林オリジナル
2024-08-14 17:28:13820ブラウズ

useCallback VS useMemo

私たちは皆、React.useCallback と React.useMemo の使い方を知っていますが、どちらを選択すべきか混乱することがあります。

ここでは、特定の状況でどのフック関数を使用する必要があるかを理解するのに役立ついくつかのケースを示します。

import React, { useState } from 'react'

export default function App() {
  const [num1, setNum1] = useState(10)
  const [num2, setNum2] = useState(12)

  return <div>{num1 + num2}</div>
}

上記の単純な例では、HTML 要素部分で num1 + num2 によって合計を取得できますが、より複雑な計算ロジックがある場合は、それ以上行う必要はありません。

import React, { useState, useMemo } from 'react'

export default function App() {
  const [num1, setNum1] = useState(10)
  const [num2, setNum2] = useState(12)

  const sum = useMemo(() => {
    const _num1 = Number(num1),
      _num2 = Number(num2)
    if (Number.isNaN(_num1) || Number.isNaN(_num2)) {
      return "check your num's type"
    }
    return _num1 + _num2
  }, [num1, num2])

  return <div>{sum}</div>
}

このコード ブロック例では、num1 + num2 の結果値を保持するために useMemo を選択しましたが、num1 または num2 の型が数値であることを完全には信頼できないため、型チェック ロジックを追加しています。問題が発生した場合は、プレースホルダー テキストが表示されます。

この状況では、HTML 部分では 1 行の単純なコードではこの効果を実現できません。もちろん、条件演算子を使用して HTML 部分にロジック コードを記述することもできます (JSX ではそれが可能です)。ただし、コストがかかるため、コードの可読性が犠牲になります。

したがって、このケースを処理するには useMemo が適しています。

OK、もう 1 つ複雑なケースに進みましょう。

import React, { useState, useMemo } from 'react'

export default function App() {
  const [num1, setNum1] = useState(10)
  const [num2, setNum2] = useState(12)
  const [num3, setNum3] = useState(100)
  const [num4, setNum4] = useState(120)

  const sum1 = useMemo(() => {
    const _num1 = Number(num1),
      _num2 = Number(num2)
    if (Number.isNaN(_num1) || Number.isNaN(_num2)) {
      return "check your num's type"
    }
    return _num1 + _num2
  }, [num1, num2])

  return (
    <>
      <div>{sum1}</div>
      <div>{num3 + num4}</div>
    </>
  )
}

ご覧のとおり、ここには num3 と num4 があり、それらの合計をレンダリングします。 num1 + num2 のロジックも再利用したい場合はどうすればよいでしょうか?もちろん、useMemo を使用して 1 つの sum2 を定義することはできますが、num の型を検証するためにロジックを再利用することはお勧めできません。したがって、useMemo から検証ロジックを分割する必要があります。次に useCallback が表示されます!

import React, { useState, useCallback } from 'react'

const validteNumAndSum = (number1, number2) => {
  const _num1 = Number(number1),
    _num2 = Number(number2)
  if (Number.isNaN(_num1) || Number.isNaN(_num2)) {
    return "check your num's type"
  }
  return _num1 + _num2
}

export default function App() {
  const [num1, setNum1] = useState(10)
  const [num2, setNum2] = useState(12)
  const [num3, setNum3] = useState(100)
  const [num4, setNum4] = useState(120)

  const sumFunc = useCallback(validteNumAndSum, [])

  return (
    <>
      <div>{sumFunc(num1, num2)}</div>
      <div>{sumFunc(num3, num4)}</div>
    </>
  )
}

ご覧のとおり、useCallback を使用して、num の型を検証し、合計を計算するロジックを持つ新しい関数を返します。この validteNumAndSum 関数を HTML 部分で簡単に再利用します。

OK、結論部分に行きましょう:

簡単に計算できる場合 (数学やより複雑な状況)、useMemo と useCallback の両方は必要ありません。

計算ロジックが複雑で、一度だけ計算する必要がある場合は、useMemo フックを選択して計算プロセスをパッケージ化し、1 つの単純な結果を返すことができます。

ただし、同じロジックを複数回使用する場合は、useCallback を選択して記憶された関数を返し、コンポーネントで再利用できます。


useCallback の件については大変申し訳ございません。 useCallback を選択するタイミングを説明するという間違いを犯し、悪い例を作成してしまいました。

ここでもう一度試します。

import React, { useState, useCallback } from 'react'

export default function App() {
  const [base, setBase] = useState(0)
  const [num1, setNum1] = useState(10)
  const [num2, setNum2] = useState(12)
  const [num3, setNum3] = useState(100)
  const [num4, setNum4] = useState(120)

  const sumFunc = useCallback(
    (number1, number2) => {
      const _num1 = Number(number1),
        _num2 = Number(number2)
      if (Number.isNaN(_num1) || Number.isNaN(_num2)) {
        return "check your num's type"
      }
      return _num1 + _num2 + base
    },
    [base],
  )

  return (
    <>
      <input
        type="number"
        value={base}
        onChange={e => {
          setBase(Number(e.target.value))
        }}
      />
      <div>{sumFunc(num1, num2)}</div>
      <div>{sumFunc(num3, num4)}</div>
    </>
  )
}

上記のコードでは、1 つの基数を別の変数データとして追加します。すべての合計には基数の値を加算する必要があります。また、基数の値を変更する入力があるため、基数が変更されるたびに sumFunc が実行されます。変更することもできるので、それを使用して正しい結果を計算できます。

そこで、useCallback についての結論を更新します。ロジックを再利用する必要があるだけであれば、このロジックを関数にパッケージ化し、どこでも再利用できるように util 関数としてコンポーネントから分割することもできます。また、ロジックがまだコンポーネントの変数に依存している場合は、useCallback を使用してロジックをパッケージ化し、記憶された新しい関数を返すことができます。

以上がuseCallback VS useMemoの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。