Haken useCallback
reagieren
Der React useCallback
Hook gibt eine gespeicherte Callback-Funktion zurück.
Stellen Sie sich Merken als Zwischenspeichern eines Werts vor, damit er nicht neu berechnet werden muss.
Dadurch können wir ressourcenintensive Funktionen isolieren, sodass sie nicht automatisch bei jedem Rendering ausgeführt werden.
Der useCallback
Hook wird nur ausgeführt, wenn eine seiner Abhängigkeiten aktualisiert wird.
Dies kann die Leistung verbessern.
Die useCallback
und useMemo
Haken sind ähnlich. Der Hauptunterschied besteht darin, dass useMemo
ein gespeicherter Wert und useCallback
eine gespeicherte Funktion zurückgegeben werden . Mehr über useMemo erfahren Sie im Kapitel useMemo .
Problem
Ein Grund für die Verwendung useCallback
besteht darin, zu verhindern, dass eine Komponente erneut gerendert wird, es sei denn, ihre Requisiten haben sich geändert.
In diesem Beispiel könnten Sie denken, dass die Todos
Komponente nicht erneut gerendert wird, es sei denn, die todos
Änderung:
Dies ist ein ähnliches Beispiel wie im Abschnitt React.memo .
Beispiel:
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);
Versuchen Sie, dies auszuführen, und klicken Sie auf die Schaltfläche zum Erhöhen der Anzahl.
Sie werden feststellen, dass die Todos
Komponente auch dann neu gerendert wird, wenn todos
sich nichts ändert.
Warum funktioniert das nicht? Wir verwenden memo
, daher sollte die Todos
Komponente nicht erneut gerendert werden, da sich weder der todos
Zustand noch die addTodo
Funktion ändern, wenn der Zähler erhöht wird.
Dies liegt an etwas, das als "referenzielle Gleichheit" bezeichnet wird.
Jedes Mal, wenn eine Komponente neu gerendert wird, werden ihre Funktionen neu erstellt. Aus diesem Grund hat sich die addTodo
Funktion tatsächlich geändert.
Zertifiziert werden!
$ 95 REGISTRIEREN
Lösung
Um dies zu beheben, können wir den useCallback
Hook verwenden, um zu verhindern, dass die Funktion neu erstellt wird, es sei denn, dies ist erforderlich.
Verwenden Sie den useCallback
Haken, um zu verhindern, dass die Todos
Komponente unnötig neu gerendert wird:
Beispiel:
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);
Jetzt Todos
wird die Komponente nur dann neu gerendert, wenn sich die todos
Requisite ändert.