【问题标题】:I don't understand useCallback我不明白 useCallback
【发布时间】:2021-05-13 12:58:00
【问题描述】:

我需要更改复选框的选中状态,但 useCallback 会多次重新渲染组件。我不明白它是如何工作的。我已经阅读了很多关于它的资料。

const AppealsList = () => {
  const [isFiltered, setFiltered] = React.useState(false);
  console.log('rerender');

  const changeCheckBox = useCallback(() => {
    setFiltered(!isFiltered);
  }, [isFiltered]);

  return (
    <div className={classNames('appeals')}>
      <div className={classNames('appeals__filter')}>
        <input
          checked={isFiltered}
          className={classNames('appeals__input')}
          type="checkbox"
          readOnly={true}
        />
        <label
          onClick={changeCheckBox}
          className={classNames('appeals__filter-label')} />
      </div>
    </div>
  );
};

重新渲染的数量:

【问题讨论】:

  • 到目前为止,您对它有什么了解
  • 为什么要重新渲染?我认为我没有正确使用回调。我想知道在这种情况下如何使用它们。
  • Why it's rerendering? 大概是因为你点击了标签。要获得 15 次渲染,我希望您进行了 14 次点击(严格模式下为 13 次)。 useCallback 不会在组件状态发生变化时停止渲染。在某些情况下,useCallback 可能会让 child 组件跳过渲染,尽管您的代码中没有使用它。
  • 渲染不同于输出 HTML 中的某些变化。这是 react 效率的一部分,渲染组件与更新 DOM 的缓慢操作分开。对组件状态或道具的任何更改,或者由于父级或页面上的多个组件发生更改而重新安装组件,都会导致渲染执行。
  • 还要注意,在开发模式下,如果你使用严格模式,组件会渲染两次stackoverflow.com/questions/61254372/…

标签: reactjs usecallback


【解决方案1】:

这是因为您编写的回调依赖于isFiltered,因此每次单击时它都会改变。当它不依赖于回调正在改变的状态时,它的效果最好。

要创建一个不会不断变化的切换函数,让它调用 setState 函数,以便它可以利用 useState 提供的功能状态更新从以前的状态计算新状态:

const changeCheckbox = useCallback(() => {
    setFiltered(currentValue => !currentValue);
}, []); // look no dependencies!

您可以在此处阅读有关功能状态更新(从当前状态导出新状态)的信息:https://reactjs.org/docs/hooks-reference.html#functional-updates

如果新状态是使用前一个状态计算的,则可以将一个函数传递给 setState。该函数将接收之前的值,并返回一个更新的值。

【讨论】:

  • 好的。谢谢你。但是当我更改复选框状态时,它不会禁用重新渲染。我想在不重新渲染的情况下更改复选框选中状态。我想错了吗?
【解决方案2】:

setCallback 用于记忆函数,因此如果您有需要大量处理的繁重函数,则不必两次处理相同的输入。例如,如果您有一个将两个数字相加的函数并给它 4 和 3,那么它会运行该函数并记住当您在函数中输入 4 和 3 时结果是 7。所以下次它传递 4 和 3处理结果时使用记忆的结果。

useCallBack 用于记忆函数,而 useEffect 用于防止不必要的重新渲染。我认为在这种情况下您想使用 useEffect Hook?

【讨论】:

  • 您的回答似乎混淆了一些东西。 useCallback 不记住函数的执行,只记住函数的reference。它可以提高性能,但不是因为它跳过了执行功能;这是因为其他组件可以看到该功能没有改变,因此它们可以跳过重新渲染。此外,useEffect 与防止不必要的重新渲染没有任何关系。
猜你喜欢
  • 2011-02-17
  • 1970-01-01
  • 2018-04-08
  • 2017-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
  • 2010-09-07
相关资源
最近更新 更多