บทช่วย สอนตอบโต้

หน้าแรก แนะนำตัว ตอบสนอง เริ่มต้น ตอบสนอง ES6 React Render HTML ตอบโต้ JSX ส่วนประกอบปฏิกิริยา คลาสตอบโต้ ตอบสนองอุปกรณ์ประกอบฉาก ปฏิกิริยาเหตุการณ์ เงื่อนไขการตอบสนอง รายการตอบโต้ แบบฟอร์มตอบโต้ ตอบสนองเราเตอร์ บันทึกโต้ตอบ ตอบสนอง CSS จัดแต่งทรงผม ตอบสนอง Sass จัดแต่งทรงผม

ตะขอตอบสนอง

ตะขอคืออะไร? ใช้สถานะ ใช้เอฟเฟกต์ ใช้บริบท ใช้Ref ใช้ลด ใช้โทรกลับ ใช้บันทึก ตะขอแบบกำหนดเอง

แบบฝึกหัดตอบโต้

ตอบคำถาม แบบฝึกหัดตอบโต้ ใบรับรองปฏิกิริยา

ตอบสนองuseCallbackตะขอ


React useCallbackHook ส่งคืนฟังก์ชันการโทรกลับที่บันทึกไว้

ให้คิดว่าการจดบันทึกเป็นการแคชค่าเพื่อจะได้ไม่ต้องคำนวณใหม่

ซึ่งช่วยให้เราสามารถแยกฟังก์ชันที่เน้นทรัพยากรเพื่อไม่ให้ทำงานโดยอัตโนมัติในทุกการเรนเดอร์

Hook ทำงานเฉพาะเมื่อมี การuseCallbackอัปเดตการพึ่งพาอย่างใดอย่างหนึ่งเท่านั้น

นี้สามารถปรับปรุงประสิทธิภาพการทำงาน

The useCallbackและuseMemoHooks มีความคล้ายคลึงกัน ความแตกต่างหลัก ๆ คือuseMemoคืนค่า ที่บันทึก และuseCallbackคืนค่าฟังก์ชันที่บันทึก คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับ useMemo ในบท useMemo


ปัญหา

เหตุผลหนึ่งที่ควรใช้useCallbackคือป้องกันไม่ให้ส่วนประกอบแสดงผลซ้ำ เว้นแต่ว่าอุปกรณ์ประกอบฉากจะมีการเปลี่ยนแปลง

ในตัวอย่างนี้ คุณอาจคิดว่าTodosส่วนประกอบจะไม่แสดงผลซ้ำ เว้นแต่จะมีการtodosเปลี่ยนแปลง:

นี่เป็นตัวอย่างที่คล้ายกับตัวอย่างในส่วนReact.memo

ตัวอย่าง:

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

ลองใช้สิ่งนี้แล้วคลิกปุ่มเพิ่มจำนวน

คุณจะสังเกตเห็นว่าTodosส่วนประกอบนั้นแสดงผลใหม่แม้ว่าองค์ประกอบtodosจะไม่เปลี่ยนแปลงก็ตาม

ทำไมสิ่งนี้ถึงใช้งานไม่ได้ เรากำลังใช้memoดังนั้นTodosส่วนประกอบไม่ควรแสดงผลซ้ำเนื่องจากtodosสถานะและaddTodoฟังก์ชันจะไม่เปลี่ยนแปลงเมื่อมีการนับเพิ่มขึ้น

นี่เป็นเพราะสิ่งที่เรียกว่า "ความเท่าเทียมกันในการอ้างอิง"

ทุกครั้งที่องค์ประกอบแสดงผลซ้ำ ฟังก์ชันจะถูกสร้างขึ้นใหม่ ด้วยเหตุนี้addTodoฟังก์ชันจึงเปลี่ยนไปจริงๆ


w3schools CERTIFIED . 2022

ได้รับการรับรอง!

ทำโมดูล React ทำแบบฝึกหัด ทำข้อสอบ และได้รับการรับรองจาก w3schools!!

$95 ลงทะเบียน

สารละลาย

ในการแก้ไขปัญหานี้ เราสามารถใช้useCallbackhook เพื่อป้องกันไม่ให้มีการสร้างฟังก์ชันขึ้นใหม่เว้นแต่จำเป็น

ใช้useCallbackHook เพื่อป้องกันไม่ให้Todosส่วนประกอบแสดงผลซ้ำโดยไม่จำเป็น:

ตัวอย่าง:

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

ตอนนี้Todosส่วนประกอบจะแสดงผลอีกครั้งเมื่อtodosเสามีการเปลี่ยนแปลง