Reageerhaak useCallback_


De React useCallbackHook retourneert een in het geheugen opgeslagen callback-functie.

Beschouw memo's als het cachen van een waarde, zodat deze niet opnieuw hoeft te worden berekend.

Dit stelt ons in staat om resource-intensieve functies te isoleren, zodat ze niet automatisch op elke render worden uitgevoerd.

The useCallbackHook wordt alleen uitgevoerd wanneer een van zijn afhankelijkheden wordt bijgewerkt.

Dit kan de prestaties verbeteren.

De useCallbacken useMemoHooks zijn vergelijkbaar. Het belangrijkste verschil is dat useMemoeen gememoriseerde waarde wordt useCallbackgeretourneerd en een gememoriseerde functie wordt geretourneerd . U kunt meer leren over useMemo in het hoofdstuk useMemo .


Probleem

Een reden om te gebruiken useCallbackis om te voorkomen dat een component opnieuw wordt weergegeven, tenzij de rekwisieten zijn gewijzigd.

In dit voorbeeld zou u kunnen denken dat de Todoscomponent niet opnieuw wordt weergegeven, tenzij de todoswijziging:

Dit is een soortgelijk voorbeeld als dat in de sectie React.memo .

Voorbeeld:

index.js

import { useState } from "react";
import ReactDOM from "react-dom";
import Todos from "./Todos";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);

  const increment = () => {
    setCount((c) => c + 1);
  };
  const addTodo = () => {
    setTodos((t) => [...t, "New Todo"]);
  };

  return (
    <>
      <Todos todos={todos} addTodo={addTodo} />
      <hr />
      <div>
        Count: {count}
        <button onClick={increment}>+</button>
      </div>
    </>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

Todos.js

import { memo } from "react";

const Todos = ({ todos, addTodo }) => {
  console.log("child render");
  return (
    <>
      <h2>My Todos</h2>
      {todos.map((todo, index) => {
        return <p key={index}>{todo}</p>;
      })}
      <button onClick={addTodo}>Add Todo</button>
    </>
  );
};

export default memo(Todos);

Probeer dit uit te voeren en klik op de knop voor het verhogen van het aantal.

U zult merken dat het Todosonderdeel opnieuw wordt weergegeven, zelfs als het todosniet verandert.

Waarom werkt dit niet? We gebruiken memo, dus de Todoscomponent mag niet opnieuw worden weergegeven, omdat noch de todosstatus noch de addTodofunctie veranderen wanneer de telling wordt verhoogd.

Dit komt door iets dat "referentiële gelijkheid" wordt genoemd.

Elke keer dat een component opnieuw wordt weergegeven, worden de functies ervan opnieuw gemaakt. Hierdoor is de addTodofunctie daadwerkelijk veranderd.


w3schools CERTIFIED . 2022

Gecertificeerd!

Voltooi de React-modules, doe de oefeningen, doe het examen en word w3schools gecertificeerd!!

$95 INSCHRIJVEN

Oplossing

Om dit op te lossen, kunnen we de useCallbackhaak gebruiken om te voorkomen dat de functie opnieuw wordt gemaakt, tenzij dat nodig is.

Gebruik de useCallbackHook om te voorkomen dat de Todoscomponent onnodig opnieuw wordt weergegeven:

Voorbeeld:

index.js

import { useState, useCallback } from "react";
import ReactDOM from "react-dom";
import Todos from "./Todos";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);

  const increment = () => {
    setCount((c) => c + 1);
  };
  const addTodo = useCallback(() => {
    setTodos((t) => [...t, "New Todo"]);
  }, [todos]);

  return (
    <>
      <Todos todos={todos} addTodo={addTodo} />
      <hr />
      <div>
        Count: {count}
        <button onClick={increment}>+</button>
      </div>
    </>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

Todos.js

import { memo } from "react";

const Todos = ({ todos, addTodo }) => {
  console.log("child render");
  return (
    <>
      <h2>My Todos</h2>
      {todos.map((todo, index) => {
        return <p key={index}>{todo}</p>;
      })}
      <button onClick={addTodo}>Add Todo</button>
    </>
  );
};

export default memo(Todos);

Nu wordt de Todoscomponent alleen opnieuw weergegeven als de todosprop verandert.