大家好,我卡颂。
尽管 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
写法呢?