2 個奇怪的 React 寫法
大家好,我卡頌。
雖然React官網用大量篇幅介紹最佳實踐,但因JSX語法的靈活性,所以總是會出現奇奇怪怪的React寫法。
本文介紹 2 種奇怪(但在某些場景下有意義)的React寫法。也歡迎大家在評論區討論你遇到過的奇怪寫法。
ref 的奇怪用法
這是一段初看讓人很困惑的代碼:
function App() {
const [dom, setDOM] = useState(null);
return <div ref={setDOM}></div>;
}
讓我們來分析下它的作用。
首先,ref有兩種形式(曾經有 3 種):
-
形如
{current: T}的數據結構 -
回調函數形式,會在
ref更新、銷燬時觸發
例子中的setDOM是useState的dispatch方法,也有兩種調用形式:
-
直接傳遞更新後的值,比如
setDOM(xxx) -
傳遞更新狀態的方法,比如
setDOM(oldDOM => return /* 一些處理邏輯 */)
在例子中,雖然反常,但ref的第二種形式和dispatch的第二種形式確實是契合的。
也就是說,在例子中傳遞給ref的setDOM方法,會在**「div 對應 DOM」**更新、銷燬時執行,那麼dom狀態中保存的就是**「div 對應 DOM」**的最新值。
這麼做一定程度上實現了**「感知 DOM 的實時變化」**,這是單純使用ref無法具有的能力。
useMemo 的奇怪用法
通常我們認爲useMemo用來緩存變量props,useCallback用來緩存函數props。
但在實際項目中,如果想通過**「緩存 props」**的方式達到子組件性能優化的目的,需要同時保證:
-
所有傳給子組件的
props的引用都不變(比如通過useMemo) -
子組件使用
React.memo
類似這樣:
function App({todos, tab}) {
const visibleTodos = useMemo(
() => filterTodos(todos, tab),
[todos, tab]);
return <Todo data={visibleTodos}/>;
}
// 爲了達到Todo性能優化的目的
const Todo = React.memo(({data}) => {
// ...省略邏輯
})
既然useMemo可以緩存變量,爲什麼不直接緩存組件的返回值呢?類似這樣:
function App({todos, tab}) {
const visibleTodos = useMemo(
() => filterTodos(todos, tab),
[todos, tab]);
return useMemo(() => <Todo data={visibleTodos}/>, [visibleTodos])
}
function Todo({data}) {
return <p>{data}</p>;
}
如此,需要性能優化的子組件不再需要手動包裹React.memo,只有當useMemo依賴變化後子組件纔會重新render。
總結
除了這兩種奇怪的寫法外,你還遇到哪些奇怪的React寫法呢?
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/fhX_npH4OwWMPkbN6ha13g