Tepki useCallbackKancası


React useCallbackHook, not alınmış bir geri arama işlevi döndürür.

Not almayı, yeniden hesaplanmasına gerek kalmaması için bir değeri önbelleğe almak olarak düşünün.

Bu, kaynak yoğun işlevleri ayırmamıza olanak tanır, böylece her işlemede otomatik olarak çalışmazlar.

Hook , useCallbackyalnızca bağımlılıklarından biri güncellendiğinde çalışır.

Bu performansı artırabilir.

useCallbackve Kancalar useMemobenzerdir. Temel fark, useMemohafızaya alınmış bir değer ve hafızaya alınmış bir işlevuseCallback döndürmesidir . useMemo bölümünde useMemo hakkında daha fazla bilgi edinebilirsiniz .


Sorun

Kullanmanın bir nedeni, useCallbackbileşenleri değişmedikçe bir bileşenin yeniden oluşturulmasını önlemektir.

TodosBu örnekte, değişiklik yapılmadıkça bileşenin yeniden oluşturulmayacağını düşünebilirsiniz todos:

Bu, React.memo bölümündeki örnekle benzerdir.

Örnek:

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

Bunu çalıştırmayı deneyin ve sayım artırma düğmesini tıklayın.

Bileşenin değişmediğinde Todosbile yeniden oluşturulduğunu fark edeceksiniz .todos

Bu neden çalışmıyor? Kullanıyoruz memo, bu nedenle , sayı artırıldığında ne durum ne de işlev değişmediğinden Todosbileşen yeniden oluşturulmamalıdır .todosaddTodo

Bunun nedeni "referans eşitliği" denen bir şey.

Bir bileşen her yeniden oluşturulduğunda, işlevleri yeniden oluşturulur. Bu nedenle, addTodoişlev aslında değişti.


w3schools CERTIFIED . 2022

Sertikalı olmak!

React modüllerini tamamlayın, alıştırmaları yapın, sınava girin ve w3schools sertifikalı olun!

95 $ KAYIT

Çözüm

Bunu düzeltmek için, useCallbackgerekli olmadıkça işlevin yeniden oluşturulmasını önlemek için kancayı kullanabiliriz.

Bileşenin gereksiz yere yeniden oluşturulmasını useCallbackönlemek için Kancayı kullanın :Todos

Örnek:

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

Artık Todosbileşen yalnızca todospervane değiştiğinde yeniden oluşturulacak.