優(yōu)化重新渲染性能的常見方法是跳過不必要的工作。 例如,可以告訴 React 重用緩存的計算,或者如果數(shù)據(jù)自上次渲染以來沒有更改,則跳過重新渲染。
要跳過計算和不必要的重新渲染,請使用以下 Hooks 之一:
-
useMemo
緩存計算結(jié)果。 -
useCallback
緩存函數(shù)定義,再傳遞給優(yōu)化組件。
要優(yōu)先考慮渲染,請使用以下 Hooks 之一: -
useTransition
將狀態(tài)轉(zhuǎn)換標(biāo)記為非阻塞并允許其他更新中斷它。 -
useDeferredValue
可以推遲更新 UI 的非關(guān)鍵部分,并讓其他部分先更新。
const cachedFn = useCallback(fn, dependencies)
定義
useCallback(fn, dependencies)
在組件中引用useCallback
import { useCallback } from 'react';
參數(shù)
fn
: 想緩存的函數(shù)。該函數(shù)可以帶參數(shù)并返回任意類型的值。返回一個函數(shù)定義,并不調(diào)用函數(shù)。dependencies
: 監(jiān)聽的變量值的列表。變量值來控制第一個參數(shù)fn是否改變。
返回值
在初次渲染,usecallback返回fn,即第一個參數(shù)傳遞的函數(shù)。
再次渲染,react會通過Object.js比較兩次dependiencies是否不同, 相同則返回上一次的函數(shù),不同則更新函數(shù)。
用法
跳過組件重新渲染
import { useCallback, useState } from "react";
export function CallbackDemo({theme}: any) {
console.log("###callback");
const [name, setName] = useState("Layor");
function handleSubmit() {
console.log("###submit");
}
return (
<div>
<div onClick={() => setName("Tom")}>callback {name}</div>
<Form onSubmit={handleSubmit}></Form>
</div>
);
}
function Form({ onSubmit }: any) {
console.log("###form");
return <div onClick={onSubmit}>input form</div>;
}
控制臺輸出:
###callback
###callback
###form
###form
接下來,我們開始優(yōu)化了。
首先使用memo
將form組件包裹起來, 再callBackDemo中定義handleSubmit函數(shù)時使用useCallback
import { useCallback, useState, memo } from "react";
export function CallbackDemo({theme}: any) {
console.log("###callback");
const [name, setName] = useState("Layor");
const handleSubmit = useCallback(function handleSubmit() {
console.log("###submit");
},[theme])
return (
<div>
<div onClick={() => setName("Tom")}>callback {name}</div>
<Form onSubmit={handleSubmit}></Form>
</div>
);
}
const Form = memo(function Form({ onSubmit }: any) {
console.log("###form"); //在click的時候不會打印
return <div onClick={onSubmit}>input form</div>;
})
useCallback我們就介紹到這里了。