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