【面試題】2056- 如何自定義一個 React Hook,用于強(qiáng)制刷新當(dāng)前組件?
共 2990字,需瀏覽 6分鐘
·
2024-05-24 09:00
文章轉(zhuǎn)載于稀土掘金技術(shù)社區(qū)——JackSonChen
寫在前面
在 react 中,如果 state 數(shù)據(jù)發(fā)生變化,我們知道,會重新渲染該組件。
但是這個前提是我們需要依賴 state 數(shù)據(jù)的變化,那比如我們并不想定義 state,又或者說我們的操作不能引起 state 的變化,此時我們也想刷新組件怎么辦?
這里我們就來實(shí)現(xiàn)一個自定義的 hooks,它的作用就是強(qiáng)制刷新當(dāng)前組件。
實(shí)現(xiàn)
如果想刷新組件,很重要的一點(diǎn)就是改變 state,當(dāng) state 的值發(fā)生變化時,組件會重新渲染。
一個重要的點(diǎn):react hook 和組件的關(guān)系
當(dāng)在組件中使用一個自定義 hook 時,這個 hook 的 狀態(tài)和邏輯會成為該組件的一部分。具體來說,hook 內(nèi)部的狀態(tài)會被 管理在使用這個 hook 的組件的狀態(tài)樹中。
通俗點(diǎn)說就是,我們自定義一個 hook,并且在組件中使用,那這個 hook 的 state 也會成為這個組件的一部分,也就是 hook 的 state 變化,會引起使用該 hook 的組件的變化。
說的太多可能還不明白,我們直接看代碼。
hook
我們先自定義一個hook,實(shí)現(xiàn)原理就是利用 state 的變化,每次調(diào)用該 hook 的時候,state 的值都會發(fā)生變化。
使用 useState 來存儲一個計數(shù)器 tick。 setTick 每次調(diào)用時會增加計數(shù)器,這會觸發(fā)組件重新渲染。 使用 useCallback 確保 forceUpdate 函數(shù)在組件的整個生命周期內(nèi)保持相同的引用。 返回 forceUpdate 函數(shù),以便在使用這個 hook 的組件中調(diào)用它。
import { useState, useCallback } from "react";
const useForceUpdate = () => {
const [, setTick] = useState(0); // 只需要 setTick 函數(shù),不需要 tick 值
const forceUpdate = useCallback(() => {
setTick(tick => tick + 1); // 使用回調(diào)函數(shù)來確保更新基于最新狀態(tài)
}, []);
return forceUpdate; // 返回 forceUpdate 函數(shù)
};
export default useForceUpdate;
忽略狀態(tài)值
這里的逗號(,)表示我們只解構(gòu)出數(shù)組的第二個元素 setTick,而忽略第一個元素。
因為我們只需要 state 發(fā)生變化,不需要使用該 state,直接寫為空也行。
const [, setTick] = useState(0);
組件使用
組件使用就比較簡單了,直接引入 useForceUpdate,并在需要調(diào)用的時機(jī)執(zhí)行即可,為了證明是否刷新,我們打印了一條語句并執(zhí)行了隨機(jī)時間顯示到頁面上,我們來看一下效果。
import React from "react";
import useForceUpdate from "./useForceUpdate";
const MyComponent = () => {
const forceUpdate = useForceUpdate(); // 獲取 forceUpdate 函數(shù)
const handleClick = () => {
forceUpdate(); // 調(diào)用 forceUpdate 函數(shù)觸發(fā)重新渲染
};
console.log('組件刷新!'); // 每次重新渲染時打印日志
return (
<div>
<p>當(dāng)前時間: {Date.now()}</p>
<button onClick={handleClick}>強(qiáng)制刷新</button>
</div>
);
};
export default MyComponent;
總結(jié)一下
為什么 MyComponent 會刷新?
當(dāng)我們在 MyComponent 中使用 useForceUpdate hook 時,useForceUpdate 內(nèi)部的狀態(tài) tick 會成為 MyComponent組件 的一部分。
調(diào)用 forceUpdate 函數(shù)會更新 tick 狀態(tài),觸發(fā) MyComponent 的重新渲染。
這是因為 react 的狀態(tài)更新機(jī)制會導(dǎo)致使用該狀態(tài)的組件重新渲染,即使這個狀態(tài)在組件中沒有直接使用。
