一个清除React依赖的小技巧

186 阅读1分钟
import React, { useCallback, useState } from 'react'

function List () {
  const [list, setList] = useState<any[]>([])
  const addList = useCallback((li) => setList([...list, li]), [list])

  return (
    <div>
      {list.map(li => <Item key={li.id} data={li} onClick={addList} />)}
    </div>
  )
}

在上面的例子中:
我们知道当且仅当传入的props发送生了变化,Item会引起重新渲染。
我们希望每个Item只受自身数据的影响,而不包括onClick回调函数的变化。
所以我们会将回调函数包裹上一层useCallback。

reactjs.org/docs/hooks-…
在react的官网中,useState的API提示里面说明了:

React 会确保 setState 函数的标识是稳定的,并且不会在组件重新渲染时发生变化。这就是为什么可以安全地从 useEffect 或 useCallback 的依赖列表中省略 setState。

通常,我们会给useCallback加上依赖的的引用,以确保callback保存的回调函数数据的正确性。

但是addList这个函数的引用里面包含了list。
所以每次调用一次addList,都会引起依赖的变更,即每个Item都会re-render。
这是我们不想看到的。
我们可以利用setState的函数参数:

  const AddList = useCallback((todo) => {
    setList(currentTodos => [...currentTodos, todo])
  }, [])

现在,每次addList调用的时候都不会引起其他Item的重新渲染。
我们成功的减少了一个state依赖!