ตะขอเป็นฟังก์ชันที่ใช้ซ้ำได้ อนุญาตให้คุณใช้ รัฐ และคุณสมบัติอื่นๆ (เช่น วิธีวงจรชีวิต และอื่นๆ) โดยไม่ต้องเขียนคลาส ฟังก์ชันเบ็ดทำให้เรา "เชื่อมต่อ" 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 เหล่านี้ในแอปพลิเคชันของคุณเพื่อความเข้าใจที่ดีขึ้น เพื่อที่คุณจะได้รู้เชิงลึกมากขึ้นโดยดูจากแหล่งข้อมูลต่อไปนี้: