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依赖!