乐趣区

关于前端:2个奇怪的React写法

大家好,我卡颂。

尽管 React 官网用大量篇幅介绍最佳实际,但因 JSX 语法的灵活性,所以总是会呈现奇奇怪怪的 React 写法。

本文介绍 2 种奇怪(但在某些场景下有意义)的 React 写法。也欢送大家在评论区探讨你遇到过的奇怪写法。

欢送退出人类高质量前端交换群,带飞

ref 的奇怪用法

这是一段初看让人很困惑的代码:

function App() {const [dom, setDOM] = useState(null);
 
  return <div ref={setDOM}></div>;
}

让咱们来剖析下它的作用。

首先,ref有两种模式(已经有 3 种):

  1. 形如 {current: T} 的数据结构
  2. 回调函数模式,会在 ref 更新、销毁时触发

例子中的 setDOMuseStatedispatch 办法,也有两种调用模式:

  1. 间接传递更新后的值,比方setDOM(xxx)
  2. 传递更新状态的办法,比方setDOM(oldDOM => return /* 一些解决逻辑 */)

在例子中,尽管反常,但 ref 的第二种模式和 dispatch 的第二种模式的确是符合的。

也就是说,在例子中传递给 refsetDOM办法,会在 div 对应 DOM 更新、销毁时执行,那么 dom 状态中保留的就是 div 对应 DOM 的最新值。

这么做肯定水平上实现了 感知 DOM 的实时变动 ,这是单纯应用ref 无奈具备的能力。

useMemo 的奇怪用法

通常咱们认为 useMemo 用来缓存变量 propsuseCallback 用来缓存函数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 写法呢?

退出移动版