Reactjs useLayoutEffect、useRef超过了最大更新深度

Reactjs useLayoutEffect、useRef超过了最大更新深度,reactjs,react-hooks,Reactjs,React Hooks,我有以下组成部分: // component.js import React from 'react'; import useComponentSize from 'useComponentSize'; const component = () => { const [comSize, comRef] = useComponentSize(); return ( <div style={{width: '100%'}} ref={comRef}>

我有以下组成部分:

// component.js
import React from 'react';
import useComponentSize from 'useComponentSize';

const component = () => {
  const [comSize, comRef] = useComponentSize();

  return (
    <div style={{width: '100%'}} ref={comRef}>
      <p>hi</p>
    </div>
  );
};
但由于一个我无法计算的原因,它总是超过最大更新深度。我已经尝试过让
useLayoutEffect
依赖于
resizeRef
,我认为这会起作用,但它不会再次更新(这正是我期望ref起作用的方式)

我应该怎么做才能使它正常工作,最重要的是,为什么上面的内容会导致无限循环


编辑:第二次尝试使用事件侦听器,仍然失败。我在这里遗漏了什么概念

// component.js
import React, { useRef } from 'react';
import useComponentSize from 'useComponentSize';

const component = () => {
  const ref = useRef();
  const [comSize] = useComponentSize(ref);

  return (
    <div style={{width: '100%'}} ref={ref}>
      <p>hi</p>
    </div>
  );
};
上面的编辑是基于这个钩子的,它工作得很好(我现在使用它作为替代品,尽管我还是希望上面的内容能够工作,尤其是知道为什么它不工作)



我试图实现的一个小解释,因为之前没有明确说明:我希望在引用组件的大小更改时,状态
size
更新。也就是说,如果窗口调整大小,并且组件保持相同大小,则不应更新。但是如果组件大小确实发生了变化,那么
大小
状态应该改变值以反映这一点。

您的代码会陷入无限循环,因为您没有将依赖项数组传递给
useEffectLayout
钩子

实际上,您根本不需要使用
useffectlayout
hook。您可以使用观察对DOM元素的更改

p.S:尽管OP的问题已经通过在问题下的一条评论中发布的演示得到了解决,但我将为将来可能看到这个问题的任何人发布一个答案

示例:

const useComponentSize=(comRef)=>{
const[size,setSize]=React.useState({
宽度:0,
身高:0
});
React.useffect(()=>{
const sizeObserver=新的调整大小的观察者((条目,观察者)=>{
entries.forEach({target})=>{
设置大小({width:target.clientWidth,height:target.clientHeight});
});
});
sizeObserver.observe(comRef.current);
return()=>sizeObserver.disconnect();
},[comRef]);
返回[大小];
};
函数App(){
const comRef=React.useRef();
常量[comSize]=使用组件大小(comRef);
返回(
{JSON.stringify(comSize)}
);
}
render(,document.getElementById(“根”))


您是否尝试了
useffect
而不是
useLayoutEffect
dice@pilchard我认为它是用来毁灭的。让我再检查一下文件@Yousaf,我也尝试过你的方法,它只在第一次更新。当我调整组件大小时,它不会更新!该解决方案不观察DOM元素的更改。您可以使用
ResizeObserver
获取初始大小并观察更改。试试这个你对
useLayoutEffect
完全正确-我假设我需要
useffect
来监控更改,并且
useLayoutEffect
需要首先渲染ref。特别感谢您的更正,并将我指给观察家看
// component.js
import React, { useRef } from 'react';
import useComponentSize from 'useComponentSize';

const component = () => {
  const ref = useRef();
  const [comSize] = useComponentSize(ref);

  return (
    <div style={{width: '100%'}} ref={ref}>
      <p>hi</p>
    </div>
  );
};
import {
  useRef,
  useState,
  useLayoutEffect,
} from 'react';

const useComponentSize = (ref) => {
  const [size, setSize] = useState();

  useLayoutEffect(() => {
    const updateSize = () => {
      setSize(ref.current.clientWidth);
    }
    
    ref.current.addEventListener('resize', updateSize);
    updateSize();
    
    return () => window.removeEventListener('resize', updateSize);
  }, []);
  
  return [size];
};

export default useComponentSize;