useCallback依赖数组不包含数据时为什么组件不更新?
我在做一个表格组件时遇到奇怪的问题,当用useCallback包裹行点击处理函数后,虽然数据更新了但组件没重新渲染。尝试过把setData放进依赖数组,但这样又会无限渲染。
代码大概是这样的:
const Table = ({ rows }) => {
const [selectedId, setSelectedId] = useState(null);
const handleRowClick = useCallback((id) => {
setSelectedId(id);
}, []); // 这里依赖数组空着
return (
<table>
{rows.map(row => (
<tr onClick={() => handleRowClick(row.id)}>
<td>{row.name}</td>
</tr>
))}
</table>
);
};
当父组件传入新的rows数据时,点击行后selectedId虽然变化了,但表格行样式没更新。控制台没有报错,这是useCallback的使用问题吗?
useCallback的依赖数组为空,导致handleRowClick没有感知到rows的变化。虽然你的数据更新了,但因为依赖数组为空,handleRowClick始终是之前的版本,行点击时传入的row.id可能还是旧的数据。解决办法是把
rows加入到依赖数组中,但直接加可能会引发无限渲染的问题,所以可以用一个技巧:不要直接依赖rows,而是通过父组件传入的最新值来处理。试试这样改:
这里的关键是,
useCallback的依赖数组需要包含所有可能影响函数逻辑的变量。如果你担心性能问题,可以确保rows只有在必要时才更新,或者用React.memo包裹子组件来优化渲染。最后,记得给每一行加上唯一的
key(比如row.id),不然 React 可能会因为缺少标识而无法正确更新 DOM。