本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com
大家好,我卡颂。
虽然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写法呢?
彦祖,亦菲,点个**「在看」**吧