使用引用中的信息设置状态时发生无限重渲染循环

时间:2019-04-11 17:45:38

标签: reactjs ecmascript-6 react-hooks

我有一个使用useState钩子来设置状态的父功能组件(此问题在钩子中的事实应该是不相关的,因为我在使用类组件时遇到了相同的行为),并且它需要为某些信息设置状态在渲染子级时会聚集,但是在设置状态时,它会再次渲染子级,从而导致无限循环

export const SomeConst = (props) => {

  const [information, setInformation] = useState([]);
  const newInfo = []

    const reportBoundingRectWithIndex = (index) => {
      return (width, left) => {
        newInfo[index] = { width, left };
        setInformation(newInfo);
      };
    };

  return (
    {children.map(child => (
        <ChildComponent
            reportBoundingRect={reportBoundingRectWithIndex(index)}
            />
        ))}
    )}

呈现的子组件在useEffect中具有此属性(使用useRef创建optionElement):

useEffect(() => {
const elementInfo = optionElement.current.getBoundingClientRect();
props.reportBoundingRect(elementInfo.width, elementInfo.left); });

这只是代码的简化版本,我添加了此const newInfo来收集此新的信息数组,没有它,宽度和剩余信息将从内存中丢失,因为setState是异步的并等待更多更改(但是当它真正被调用时,该信息将不再存在,并且在该数组中变得不确定。

我在有状态的组件中尝试了此操作,但是componentDidMount和setState的结果以及所有内容都是相同的,我真的很想获得一些有关如何实现上述行为的指针

非常感谢您的帮助

1 个答案:

答案 0 :(得分:0)

因此,代码中的问题是子useEffect中的子项不应该在每次更新时都被调用,否则会导致无限循环,因为useEffect中的调用父函数会更新状态并导致重新渲染,从而再次触发useEffect

export const SomeConst = (props) => {

  const [information, setInformation] = useState([]);
  const newInfo = []

    const reportBoundingRectWithIndex = (index) => {
      return (width, left) => {
        newInfo[index] = { width, left };
        setInformation(newInfo);
      };
    };

  return (
    {children.map(child => (
        <ChildComponent
            reportBoundingRect={reportBoundingRectWithIndex(index)}
            />
        ))}
    )}
  )
}

在子调用中,useEffect仅在初始渲染(或某些更改)时起作用

useEffect(() => {
   const elementInfo = optionElement.current.getBoundingClientRect();
   props.reportBoundingRect(elementInfo.width, elementInfo.left);
}, []);