React Hooks: Deep Cuts PlatoBlockchain Data Intelligence ค้นหาแนวตั้ง AI.

React Hooks: บาดแผลลึก

ตะขอเป็นฟังก์ชันที่ใช้ซ้ำได้ อนุญาตให้คุณใช้ รัฐ และคุณสมบัติอื่นๆ (เช่น วิธีวงจรชีวิต และอื่นๆ) โดยไม่ต้องเขียนคลาส ฟังก์ชันเบ็ดทำให้เรา "เชื่อมต่อ" the ปฏิกิริยาของวงจรชีวิต การใช้ส่วนประกอบที่ใช้งานได้ ทำให้เราสามารถจัดการสถานะของส่วนประกอบการทำงานของเราได้โดยไม่ต้องแปลงเป็นองค์ประกอบคลาส

เกิดปฏิกิริยา แนะนำตะขอ ย้อนกลับไปในเวอร์ชัน 16.8 และได้เพิ่มมากขึ้นตั้งแต่นั้นเป็นต้นมา บางคนใช้และเป็นที่นิยมมากกว่าคนอื่นเช่น useEffect, useStateและ useContext ตะขอ ฉันไม่สงสัยเลยว่าคุณเข้าถึงมันได้ถ้าคุณทำงานกับ React

แต่สิ่งที่ฉันสนใจคือ React hooks ที่ไม่ค่อยมีคนรู้จัก แม้ว่า React hooks ทั้งหมดจะมีความน่าสนใจในแบบของตัวเอง แต่ก็มีอยู่ XNUMX แบบที่ฉันต้องการแสดงให้คุณเห็นจริงๆ เพราะพวกเขาอาจไม่ปรากฏในงานประจำวันของคุณ — หรือบางทีพวกเขาอาจทำและรู้ว่าพวกมันให้พลังพิเศษแก่คุณ

สารบัญ

useReducer

พื้นที่ useReducer hook เป็นเครื่องมือจัดการสถานะเช่นเดียวกับ hooks อื่น ๆ โดยเฉพาะมันเป็นทางเลือกแทน useState ตะขอ.

ถ้าคุณใช้ useReducer ขอเปลี่ยนสถานะสองสถานะขึ้นไป (หรือการกระทำ) คุณไม่จำเป็นต้องจัดการสถานะเหล่านั้นทีละรายการ เบ็ดติดตามสถานะทั้งหมดและจัดการโดยรวม กล่าวอีกนัยหนึ่งคือจัดการและแสดงผลการเปลี่ยนแปลงสถานะอีกครั้ง ไม่เหมือนกับ useState ตะขอ, useReducer ง่ายกว่าเมื่อต้องจัดการกับหลายรัฐในโครงการที่ซับซ้อน

ใช้กรณี

useReducer สามารถช่วยลดความซับซ้อนในการทำงานกับหลายสถานะได้ ใช้เมื่อคุณพบว่าตัวเองจำเป็นต้องติดตามสถานะต่างๆ รวมกัน เนื่องจากช่วยให้คุณสามารถจัดการกับการจัดการสถานะและตรรกะการแสดงผลของส่วนประกอบเป็นข้อกังวลที่แยกจากกัน

วากยสัมพันธ์

useReducer ยอมรับสามอาร์กิวเมนต์ ซึ่งหนึ่งในนั้นเป็นทางเลือก:

  • ฟังก์ชั่นลด
  • initialState
  • an init ฟังก์ชั่น (ไม่จำเป็น)
const [state, dispatch] = useReducer(reducer, initialState)
const [state, dispatch] = useReducer(reducer, initialState initFunction) // in the case where you initialize with the optional 3rd argument

ตัวอย่าง

ตัวอย่างต่อไปนี้เป็นอินเทอร์เฟซที่มีการป้อนข้อความ ตัวนับ และปุ่ม การโต้ตอบกับแต่ละองค์ประกอบจะอัปเดตสถานะ สังเกตว่า useReducer ช่วยให้เราสามารถกำหนดหลายกรณีพร้อมกันแทนที่จะตั้งค่าเป็นรายบุคคล

import { useReducer } from 'react';
const reducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    case 'DECREMENT':
      return { ...state, count: state.count - 1 };
    case 'USER_INPUT':
      return { ...state, userInput: action.payload };
    case 'TOGGLE_COLOR':
      return { ...state, color: !state.color };
    default:
      throw new Error();
  }
}

function App() {
  const [state, dispatch] = useReducer(reducer, { count: 0, userInput: '', color: false })

  return (
    <main className="App, App-header" style={{ color: state.color ? '#000' : '#FF07FF'}}>
      <input style={{margin: '2rem'}}
        type="text"
        value={state.userInput}
        onChange={(e) => dispatch({ type: 'USER_INPUT', payload: e.target.value })}
      />
      <br /><br />
      <p style={{margin: '2rem'}} >{state.count}</p>
      <section style={{margin: '2rem'}}>
        <button  onClick={(() => dispatch({ type: 'DECREMENT' }))}>-</button>
        <button onClick={(() => dispatch({ type: 'INCREMENT' }))}>+</button>
        <button onClick={(() => dispatch({ type: 'TOGGLE_COLOR' }))}>Color</button>
      </section>
      <br /><br />
      <p style={{margin: '2rem'}}>{state.userInput}</p>
    </main>
  );
}
export default App;

จากโค้ดด้านบน สังเกตว่าเราสามารถจัดการสถานะต่างๆ ใน ​​. ได้อย่างง่ายดายได้อย่างไร ลด (switch-case) นี้แสดงให้เห็นถึงประโยชน์ของ useReducer. นี่คือพลังที่มอบให้เมื่อทำงานในแอปพลิเคชันที่ซับซ้อนซึ่งมีหลายสถานะ

useRef

พื้นที่ useRef hook ใช้ในการสร้างการอ้างอิงองค์ประกอบเพื่อเข้าถึง DOM แต่ยิ่งไปกว่านั้น จะส่งกลับวัตถุด้วย a .current คุณสมบัติที่สามารถใช้ได้ตลอดวงจรชีวิตของส่วนประกอบ ทำให้ข้อมูลยังคงอยู่โดยไม่ทำให้เกิดการแสดงผลซ้ำ ดังนั้น useRef ค่ายังคงเหมือนเดิมระหว่างการแสดงผล; การอัปเดตข้อมูลอ้างอิงจะไม่ทำให้เกิดการแสดงผลซ้ำ

ใช้กรณี

เข้าถึงไฟล์ useRef ขอเมื่อคุณต้องการ:

  • จัดการ DOM ด้วยข้อมูลที่ไม่แน่นอนที่เก็บไว้
  • เข้าถึงข้อมูลจากองค์ประกอบย่อย (องค์ประกอบที่ซ้อนกัน)
  • ตั้งโฟกัสที่องค์ประกอบ

มีประโยชน์มากที่สุดเมื่อจัดเก็บข้อมูลที่เปลี่ยนแปลงได้ในแอปของคุณโดยไม่ทำให้เกิดการแสดงผลซ้ำ

วากยสัมพันธ์

useRef ยอมรับเพียงอาร์กิวเมนต์เดียวเท่านั้น ซึ่งก็คือ ค่าเริ่มต้น.

const newRefComponent = useRef(initialValue);

ตัวอย่าง

ที่นี่ฉันใช้ useRef และ useState ขอแสดงจำนวนครั้งที่แอปพลิเคชันแสดงสถานะที่อัปเดตเมื่อพิมพ์ในการป้อนข้อความ

import './App.css'

function App() {
  const [anyInput, setAnyInput] = useState(" ");
  const showRender = useRef(0);
  const randomInput = useRef();
  const toggleChange = (e) => {
    setAnyInput (e.target.value);
    showRender.current++;
  
  }
  const focusRandomInput = () => {
    randomInput.current.focus();
  }

  return (
    <div className="App">
      <input className="TextBox" 
        ref ={randomInput} type="text" value={anyInput} onChange={toggleChange}
      />
      <h3>Amount Of Renders: {showRender.current}</h3>
      <button onClick={focusRandomInput}>Click To Focus On Input </button>
    </div>
  );
}

export default App;

สังเกตว่าการพิมพ์อักขระแต่ละตัวในช่องข้อความจะอัปเดตสถานะของแอปอย่างไร แต่จะไม่ทริกเกอร์การแสดงผลซ้ำทั้งหมด

useImperativeHandle

คุณรู้หรือไม่ว่าองค์ประกอบลูกสามารถเข้าถึงฟังก์ชั่นการโทรที่ส่งผ่านมาจากองค์ประกอบหลักได้อย่างไร? ผู้ปกครองส่งต่อสิ่งเหล่านั้นผ่านอุปกรณ์ประกอบฉาก แต่การถ่ายโอนนั้นเป็น "ทิศทางเดียว" ในแง่ที่ว่าผู้ปกครองไม่สามารถเรียกใช้ฟังก์ชันที่อยู่ในเด็กได้

ดี useImperativeHandle ทำให้ผู้ปกครองสามารถเข้าถึงฟังก์ชันขององค์ประกอบลูกได้

ทำงานอย่างไร

  • ฟังก์ชั่นถูกกำหนดไว้ในองค์ประกอบย่อย
  • A ref ถูกเพิ่มในพาเรนต์
  • เราใช้ forwardRefอนุญาตให้ ref ที่ถูกกำหนดให้ส่งต่อไปยังลูก
  • useImperativeHandle เปิดเผยการทำงานของเด็กผ่านทาง ref.

ใช้กรณี

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

วากยสัมพันธ์

useImperativeHandle (ref, createHandle, [dependencies])

ตัวอย่าง

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

// Parent component
import React, { useRef } from "react";
import ChildComponent from "./childComponent";
import './App.css';

function useImperativeHandle() {
  const controlRef = useRef(null);
  return (
    onClick={
      () => {
        controlRef.current.controlPrint();
      }
    }
    >
    Parent Box
  );
}
export default useImperativeHandle;
// Child component
import React, { forwardRef, useImperativeHandle, useState } from "react";

const ChildComponent = forwardRef((props, ref) => {
  const [print, setPrint] = useState(false);
  useImperativeHandle(ref, () => ({
    controlPrint() 
    { setPrint(!print); },
  })
  );

  return (
    <>
    Child Box
    { print && I am from the child component }
  );
});

export default ChildComponent;

เอาท์พุต

useMemo

useMemo เป็นหนึ่งใน React hooks ที่ใช้งานน้อยที่สุด แต่น่าสนใจที่สุด มันสามารถปรับปรุงประสิทธิภาพและลดเวลาในการตอบสนอง โดยเฉพาะอย่างยิ่งในการคำนวณขนาดใหญ่ในแอปของคุณ ได้อย่างไร? ทุกครั้งที่มีการอัปเดตสถานะของส่วนประกอบและแสดงส่วนประกอบซ้ำ useMemo hook ป้องกันไม่ให้ React ต้องคำนวณค่าใหม่

คุณเห็นไหม ฟังก์ชันตอบสนองต่อการเปลี่ยนแปลงสถานะ ดิ useMemo เบ็ดทำหน้าที่และ ส่งคืนค่าที่ส่งคืนของฟังก์ชันนั้น. โดยจะแคชค่านั้นเพื่อป้องกันการใช้ความพยายามเพิ่มเติมในการแสดงผลซ้ำ จากนั้นส่งคืนเมื่อการขึ้นต่อกันมีการเปลี่ยนแปลง

กระบวนการนี้เรียกว่า การบันทึก และเป็นสิ่งที่ช่วยเพิ่มประสิทธิภาพโดยการจดจำค่าจากคำขอครั้งก่อน เพื่อให้สามารถกลับมาใช้งานได้อีกครั้งโดยไม่ต้องคำนวณซ้ำ

ใช้กรณี

กรณีการใช้งานที่ดีที่สุดคือทุกครั้งที่คุณทำงานกับการคำนวณจำนวนมาก ซึ่งคุณต้องการเก็บค่าและใช้ในการเปลี่ยนแปลงสถานะในภายหลัง อาจเป็นชัยชนะด้านประสิทธิภาพที่ดี แต่การใช้มากเกินไปอาจส่งผลตรงกันข้ามโดยการใช้หน่วยความจำของแอป

วากยสัมพันธ์

useMemo( () => 
  { // Code goes here },
  []
)

ตัวอย่าง

เมื่อคลิกปุ่ม โปรแกรมขนาดเล็กนี้จะระบุเวลาที่ตัวเลขเป็นคู่หรือคี่ จากนั้นยกกำลังสองค่า ฉันเพิ่มเลขศูนย์จำนวนมากในลูปเพื่อเพิ่มพลังในการคำนวณ ส่งคืนค่าเป็นวินาทีที่หกและยังคงทำงานได้ดีเนื่องจาก useMemo ตะขอ.

// UseMemo.js
import React, { useState, useMemo } from 'react'

function Memo() {
  const [memoOne, setMemoOne] = useState(0);
  const incrementMemoOne = () => { setMemoOne(memoOne + 1) }
  const isEven = useMemo(() => { 
    let i = 0 while (i < 2000000000) i++ return memoOne % 2 === 0
  },
  [memoOne]);
  
  const square = useMemo(()=> { 
    console.log("squared the number"); for(var i=0; i < 200000000; i++);
    return memoOne * memoOne;
  },
  [memoOne]);

  return (
    Memo One - 
    { memoOne }
    { isEven ? 'Even' : 'Odd' } { square } 
  );
}
export default Memo

เอาท์พุต

useMemo เป็นเพียงเล็กน้อยเช่น useCallback ขอเกี่ยวแต่ข้อแตกต่างคือ useMemo สามารถเก็บค่าที่บันทึกไว้จากฟังก์ชัน โดยที่ useCallback เก็บฟังก์ชันที่จดจำไว้เอง

useCallback

พื้นที่ useCallback ขอเป็นอีกเรื่องที่น่าสนใจและส่วนสุดท้ายเป็นการเตือนสปอยเลอร์สำหรับสิ่งที่ทำ

อย่างที่เราเพิ่งเห็นว่า useCallback ทำงานเหมือน useMemo ขอว่าพวกเขาทั้งคู่ใช้การท่องจำเพื่อแคชบางอย่างเพื่อใช้ในภายหลัง ในขณะที่ useMemo เก็บการคำนวณของฟังก์ชันเป็นค่าที่เก็บไว้ useCallback เก็บและส่งคืนฟังก์ชัน

ใช้กรณี

Like useMemo, useCallback เป็นการเพิ่มประสิทธิภาพการทำงานที่ดีในการจัดเก็บและส่งคืนการโทรกลับที่บันทึกไว้และการพึ่งพาใด ๆ โดยไม่ต้องแสดงผลซ้ำ

วากยสัมพันธ์

const getMemoizedCallback = useCallback (
  () => { doSomething () }, []
);

ตัวอย่าง


{ useCallback, useState } from "react";
import CallbackChild from "./UseCallback-Child";
import "./App.css"

export default function App() {
  const [toggle, setToggle] = useState(false);
  const [data, setData] = useState("I am a data that would not change at every render, thanks to the useCallback");
  const returnFunction = useCallback(
    (name) => 
    { return data + name; }, [data]
  );
  return (
    onClick={() => {
      setToggle(!toggle);
    }}
    >
    {" "}

    // Click To Toggle
    { toggle && h1. Toggling me no longer affects any function } 
  ); 
}
// The Child component
import React, { useEffect } from "react";

function CallbackChild(
  { returnFunction }
) {
  useEffect(() => 
    { console.log("FUNCTION WAS CALLED"); },
    [returnFunction]);
  return { returnFunction(" Hook!") };
}
export default CallbackChild;

เอาท์พุต

ความคิดสุดท้าย

เราจะไปที่นั่น! เราเพิ่งดูห้าตะขอ React ที่มีประโยชน์มากซึ่งฉันคิดว่ามักถูกมองข้าม เช่นเดียวกับการปัดเศษหลายๆ อย่างนี้ เราแค่ขูดพื้นผิวของตะขอเหล่านี้ พวกเขาแต่ละคนมีความแตกต่างและข้อควรพิจารณาในการพิจารณาเมื่อคุณใช้ แต่หวังว่าคุณจะมีความคิดที่ดีในระดับสูงว่ามันคืออะไร และเมื่อใดที่มันอาจเหมาะสมกว่าตะขออื่นๆ ที่คุณอาจหยิบใช้บ่อยๆ

วิธีที่ดีที่สุดในการทำความเข้าใจพวกเขาอย่างถ่องแท้คือการฝึกฝน ดังนั้นฉันจึงแนะนำให้คุณฝึกใช้ hooks เหล่านี้ในแอปพลิเคชันของคุณเพื่อความเข้าใจที่ดีขึ้น เพื่อที่คุณจะได้รู้เชิงลึกมากขึ้นโดยดูจากแหล่งข้อมูลต่อไปนี้:

ประทับเวลา:

เพิ่มเติมจาก เคล็ดลับ CSS