当前位置: 首页 > 知识库问答 >
问题:

反应自定义钩子批更新

公孙涵育
2023-03-14

据我所知,useState钩子的更新函数应该在批处理中运行,而不是在每次调用组件时重新呈现它。我创建了以下自定义挂钩:

function useObservable(source) {
  const [v, setV] = useState();

  useEffect(() => {
    const subscription = source.subscribe(setV);

    return () => subscription.unsubscribe();
  }, [source]);

  return v;
}

但当我多次使用它时,每次发射都会导致重新渲染:

const subject = new Subject();

setTimeout(() => {
  subject.next("Value");
}, 1000);

function App() {
  const value = useObservable(subject);
  const value2 = useObservable(subject);
  const value3 = useObservable(subject);

  console.log("render"); <=== called 3 times

  return (
    <div>
      <p>{value}</p>
    </div>
  );
}

有没有办法优化这个?我是不是误解了什么?

共有1个答案

章稳
2023-03-14

看来你用的是ReactStrictMode模式,这就是为什么你看到2个第一个渲染。如果将useState与React一起使用。开发中的StrictMode、useState和其他一些函数将导致React双重渲染。React这样做是为了检测副作用(https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects)。

第三次渲染是由源代码引起的。订阅(setV) 。因为主体生成值并调用观察者(setV),从而导致第三次渲染。

如果你删除反应。StrictMode或在生产中测试它,您将只看到2个渲染。

关于useState以及它导致双重渲染的原因也有很好的解释:React useState cause double rendering

 类似资料:
  • 和其它版本控制系统一样,Git 能在特定的重要动作发生时触发自定义脚本。 有两组这样的钩子:客户端的和服务器端的。 客户端钩子由诸如提交和合并这样的操作所调用,而服务器端钩子作用于诸如接收被推送的提交这样的联网操作。 你可以随心所欲地运用这些钩子。 安装一个钩子 钩子都被存储在 Git 目录下的 hooks 子目录中。 也即绝大部分项目中的 .git/hooks 。 当你用 git init 初始

  • 我正在尝试使用react钩子创建一个悬停以显示div,我遇到了以下问题: 第69:31行:在函数“renderHideOptionalClauseTrigger”中调用React钩子“useState”,该函数既不是React函数组件,也不是自定义React钩子函数React钩子/钩子规则 搜索关键字以了解有关每个错误的更多信息。 以下是我的代码库:

  • 我在关注丹·阿布拉莫夫的这篇文章: https://overreacted.io/making-setinterval-declarative-with-react-hooks/ 在本文中,Dan制作了一个自定义的useInterval钩子,以创建一个动态的setInterval。 钩子看起来像这样: 但有一部分我不明白,那就是: 我理解,如果延迟更改,则调用此useEffect。回调被分配给ti

  • 我有一个函数,它运行验证并根据检查结果设置状态变量。我需要通过API调用传递要上传的变量。 我的问题是状态变量没有更新,当我需要在api调用中传递更新的变量时,状态变量正在以初始状态(null)传递。 我该如何着手解决这个问题? 现行代码 更新的代码正在运行

  • 我正在尝试新的hooks功能,并坚持认为我的状态没有更新。 实际上,状态已更新(我可以在console.log中看到更新的值,并且我的组件会重新运行useEffect),但是useEffect方法使用我的旧状态,并仅将签名保存给第一个用户,而活动用户在状态中确实发生了更改。 我想过添加useCallback,并将我的方法移动到use效果或组件本身,但我可以设法让它工作。 状态: 这是我的效果: 这

  • 我有一个组件,我在其中调用我的自定义钩子。 自定义钩子如下所示: 而我在其中使用的导致错误的组件是: 有什么想法吗?