React.js钩子从事件监听器设置状态函数

时间:2019-09-16 23:55:17

标签: javascript reactjs

能否请您解释以下原因导致无限循环并出现以下错误:

  

未捕获的不变违规:重新渲染过多。 React限制了渲染次数以防止无限循环。

import React from "react";
import { useState } from 'react';

function MyImageComponent(props) {
  const {
    images
  } = props;

  const [windowWidth, updateWindowDimensions] = useState(window.innerWidth);

  window.addEventListener('resize', updateWindowDimensions(window.innerWidth)); //error here


  return (
    <div>
    {windowWidth}
    </div>
  );

}

export default MyImageComponent;

我相信我可以使用useEffect API来解决问题,但我从概念上不了解问题是什么...似乎多次调用渲染,因为状态是在循环中设置的...但鉴于更新功能updateWindowDimensions已绑定到事件监听器,该监听器不会无限运行,所以我不理解。

请注意:无论是否调整窗口大小,都会显示该错误。

2 个答案:

答案 0 :(得分:2)

当前,您没有正确处理调整大小事件处理程序。调整大小事件处理程序的第一个参数为https://www.gams.com/latest/docs/S_ANTIGONE.html。同样,您会将函数传递给处理程序,而不是将函数作为处理程序执行。请尝试以下操作:

window.addEventListener('resize', () => updateWindowDimensions(window.innerWidth))

希望有帮助!

答案 1 :(得分:2)

@Alexander Staroselsky答案将解决您的确切问题,但是在每个渲染器window.addEventListener上将被调用,并且新的事件处理程序将分配给“调整大小”事件。因此,您很快就会得到数百个相同的事件监听器,它们调用updateWindowDimensions(window.innerWidth)(您可以通过在回调中添加console.log(window.innerWidth)来看到它。)

我建议将useEffect与空的依赖项列表一起使用。因此它将只被调用一次,并将一个事件侦听器绑定到resize事件。

useEffect(() => {
    window.addEventListener('resize', () => {
        updateWindowDimensions(window.innerWidth)
  })}, []);