Memahami caching pergantungan dan rujukan useCallback dalam React
P粉044526217
P粉044526217 2023-08-15 19:29:37
0
1
576
<p>Adakah cangkuk useCallback hanya cache rujukan fungsi atau juga nilai/hasil fungsi itu sendiri? Juga, adakah menggunakan ref dalam tatasusunan kebergantungan sebenarnya mempunyai sebarang kesan, seperti ref komponen? Jika tidak, adakah terdapat cara untuk memastikan perubahan pada nilai rujukan mempunyai kesan yang sesuai? </p> <p>Saya pada asalnya menyangka bahawa hanya rujukan fungsi akan dicache, tetapi selepas membaca artikel saya mengetahui bahawa useCallback(fn, deps) adalah bersamaan dengan useMemo(() => fn, deps), dan saya tidak pasti jika ini berlaku Ini sebenarnya berlaku. Selain itu, saya cuba menggunakan ref komponen sebagai kebergantungan (seperti Video.js dan react-slick), tetapi saya fikir ia tidak mempunyai banyak kesan berbanding kebergantungan lain. </p>
P粉044526217
P粉044526217

membalas semua(1)
P粉170438285

Ya, tujuan useCallback adalah untuk membenarkan fungsi menyimpan rujukannya antara pemaparan melainkan kebergantungan yang anda tentukan berubah.

Sebagai contoh, jika anda mempunyai fungsi f(x,y)=>x+y, anda boleh menggunakan tatasusunan kebergantungan kosong useCallback((x,y)=>x+ y,[]), fungsi ini tidak akan pernah berubah. Ia sentiasa menghasilkan tingkah laku yang konsisten kerana ia hanya menggunakan hujahnya untuk menghuraikan output. Walau bagaimanapun, ia mungkin berubah jika anda mempunyai fungsi lain h dan nilai luaran lain z, dan h ditakrifkan sebagai h(x, y)=>x+y+z, maka anda perlu memasukkan z dalam kebergantungan supaya jika z berubah, Fungsi yang dikembalikan daripada f(x,y)=>x+y,你可以使用空的依赖数组useCallback((x,y)=>x+y,[]),这个函数将永远不会改变。它始终会产生一致的行为,因为它只使用其参数来解析输出。但是,如果你有另一个函数h和另一个外部值z,它可能会发生变化,而且h定义为h(x,y)=>x+y+z,那么你需要将z包含在依赖项中,以便如果z发生变化,从useCallback akan mempunyai rujukan baru.

Jadi penggunaan useCallback的用途通常是当你传递函数时,它不会触发子组件重新渲染,或者当你在子组件的useEffect声明中使用函数作为依赖项时。如果函数内部的操作很昂贵,那么useCallback biasanya apabila anda lulus fungsi supaya ia tidak mencetuskan komponen kanak-kanak untuk dipaparkan semula, atau apabila anda menggunakan fungsi sebagai kebergantungan dalam perisytiharan useEffect komponen kanak-kanak. Jika operasi di dalam fungsi itu mahal, maka

kurang berguna dan anda harus menghafal hasilnya secara berasingan.

ref的事情,我认为在依赖项中包含ref并不会有任何作用,它就像数组为空一样。也许如果refMengenai

disimpan dalam keadaan, ia mungkin berguna, tetapi saya tidak begitu pasti.

Berikut ialah pautan https://stackblitz.com/edit/stackblitz-starters-wwyw9f?file=src%2FApp.tsx

, yang mempunyai beberapa contoh yang mungkin berguna.

Saya juga boleh menampalnya di sini jika ia mungkin dipadamkan.

import * as React from 'react';
import './style.css';

export default function App() {
  //x and y to be used as function arguments
  const [x, setX] = React.useState(0);
  const [y, setY] = React.useState(0);

  //z is variable also used in function calculation but not as an argument
  const [z, setZ] = React.useState(0);

  const ref = React.useRef<number>(0);

  //counter to see how many times function updates
  //will start at 2 cause strict mode but that's no issue really
  const [i, setI] = React.useState(0);

  //function to add x and y from args and add z from state
  const fn = React.useCallback(
    (x: number, y: number) => {
      // console.log(`${x}+${y}`);
      return x + y + z;
    },
    [z] // if you remove z and update it get wrong result
  );

  //update fn count on fn change
  React.useEffect(() => {
    setI((i) => i + 1);
  }, [fn]);

  React.useEffect(() => {
    console.log('nice');
    return () => console.log('ref cleanup');
  }, [ref]);

  return (
    <div>
      <pre>{JSON.stringify({ x, y, z })}</pre>
      <button onClick={() => setX((x) => x + 1)}> x ++</button>
      <button onClick={() => setY((y) => y + 1)}> y ++</button>
      <button onClick={() => setZ((z) => z + 1)}> z ++</button>

      <pre>x+y+z={fn(x, y)}</pre>

      <pre>fnCount:{i}</pre>

      <button
        onClick={() => {
          ref.current = ref.current++;
        }}
      >
        ref++
      </button>
    </div>
  );
}
Semoga ia dapat membantu anda🎜
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan