suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Grundlegendes zum Abhängigkeits-Caching und zur Referenzierung von useCallback in React

<p>Zwischenspeichert der useCallback-Hook nur die Funktionsreferenz oder auch den Wert/das Ergebnis der Funktion selbst? Hat die Verwendung von „ref“ in einem Abhängigkeitsarray tatsächlich irgendeine Auswirkung, wie beispielsweise der „ref“ einer Komponente? Wenn nicht, gibt es eine Möglichkeit sicherzustellen, dass Änderungen am Referenzwert die entsprechende Wirkung haben? </p> <p>Ich dachte ursprünglich, dass nur Funktionsreferenzen zwischengespeichert würden, aber nachdem ich einen Artikel gelesen hatte, erfuhr ich, dass useCallback(fn, deps) äquivalent zu useMemo(() => fn, deps) ist, und ich bin mir nicht sicher Wenn dies der Fall ist, ist dies tatsächlich der Fall. Außerdem habe ich versucht, die Referenz der Komponente als Abhängigkeit zu verwenden (wie Video.js und React-Slick), aber ich denke, dass dies im Vergleich zu anderen Abhängigkeiten keine großen Auswirkungen hat. </p>
P粉044526217P粉044526217500 Tage vor570

Antworte allen(1)Ich werde antworten

  • P粉170438285

    P粉1704382852023-08-16 09:43:21

    是的,useCallback的目的是允许函数在渲染之间保持其引用,除非你指定的依赖项发生了变化。

    例如,如果你有一个函数f(x,y)=>x+y,你可以使用空的依赖数组useCallback((x,y)=>x+y,[]),这个函数将永远不会改变。它始终会产生一致的行为,因为它只使用其参数来解析输出。但是,如果你有另一个函数h和另一个外部值z,它可能会发生变化,而且h定义为h(x,y)=>x+y+z,那么你需要将z包含在依赖项中,以便如果z发生变化,从useCallback返回的函数将具有新的引用。

    因此,useCallback的用途通常是当你传递函数时,它不会触发子组件重新渲染,或者当你在子组件的useEffect声明中使用函数作为依赖项时。如果函数内部的操作很昂贵,那么useCallback就不太有用了,你应该单独对结果进行记忆。

    关于ref的事情,我认为在依赖项中包含ref并不会有任何作用,它就像数组为空一样。也许如果ref被存储在状态中,可能会有用,但我不太确定。

    这里有一个链接https://stackblitz.com/edit/stackblitz-starters-wwyw9f?file=src%2FApp.tsx,里面有一些例子,也许有用。

    如果可能会被删除,我也可以将其粘贴过来。

    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>
      );
    }

    希望能对你有所帮助

    Antwort
    0
  • StornierenAntwort