反应自定义钩子批处理更新

时间:2020-07-12 19:37:23

标签: reactjs

据我了解,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 个答案:

答案 0 :(得分:0)

似乎您使用React.StrictMode模式,这就是为什么您看到2个第一个渲染的原因。如果在开发中将useState与React.StrictMode一起使用,useState和其他一些函数将使React呈现两次渲染。 React这样做是为了检测副作用(https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects)。

第三次渲染是由source.subscribe(setV);引起的。因为您的主题产生了价值并调用了导致第三次渲染的观察者(setV)。

如果删除React.StrictMode或在生产环境中对其进行测试,则只会看到2个渲染。

关于useState以及为什么导致双重渲染的很好解释:React useState cause double rendering