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
写法呢?
相关文章
Native Memory Tracking追踪区域示例分析
这篇文章主要为大家介绍了Native Memory Tracking追踪区域示例分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-11-11
最新评论