仅在测试时通过 useEffect 内的 useState 设置值时出现无限渲染错误

发布于 2025-01-10 10:22:36 字数 1063 浏览 2 评论 0 原文

我有以下简单的组件,我只是想在开始时设置一个值。

因此尝试在 useEffect 中设置值。

我在这里将组件简化到最小。
只要我尝试通过 useState 设置值,它就会抛出以下错误。

错误:重新渲染次数过多。 React 将渲染次数限制为 防止无限循环。

它不是外部函数。问题在于使用 useState setter 本身,因为即使将其设置为 true 也会引发相同的错误。

为什么这是一个问题?

如果我尝试在这里做一个计数器,当我注释掉 setValid 时,我只输入一次 useEffect
但是如果我调用 setValid,我会在出错之前输入 useEffect 大约 25 次。

我该如何纠正这个问题。我需要通过 useState 设置此值,以便在组件中进一步使用。请指教。

代码:

export const MyComponent = () => {
  const [valid, setValid] = React.useState(undefined);
  React.useEffect(() => {
    setValid(externalFunction());
    // setValid(true); // same error
  }, []);

  return <MyComponent />;
};

当我运行它时,效果很好。 该错误来自运行以下测试。

import { shallow } from 'enzyme';
const render = (props) => shallow(
    <MyComponent
        {...props}
    />
);

it('should render', () => {
    const renderedModule = render();
    expect(renderedModule).toMatchSnapshot();
});

I have the following simple component where I am just looking to set a value at the start.

Thus trying to set the value inside useEffect.

I have simplified the component to be minimal here.

As long as I try to set the value via useState, it throws following error.

Error: Too many re-renders. React limits the number of renders to
prevent an infinite loop.

It it not the externalFunction. Issue is with using the useState setter itself since even setting it to true throws same error.

Why is this an issue?

If I try to do a counter inside here, I only enter useEffect once when I comment out setValid.

But if I call setValid, I enter useEffect about 25 times before erroring.

How could I rectify this issue. I need to set this value via useState for use further down in the component. Please advice.

Code:

export const MyComponent = () => {
  const [valid, setValid] = React.useState(undefined);
  React.useEffect(() => {
    setValid(externalFunction());
    // setValid(true); // same error
  }, []);

  return <MyComponent />;
};

This works fine when I run it.
The error comes from running following test.

import { shallow } from 'enzyme';
const render = (props) => shallow(
    <MyComponent
        {...props}
    />
);

it('should render', () => {
    const renderedModule = render();
    expect(renderedModule).toMatchSnapshot();
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

执笔绘流年 2025-01-17 10:22:36

给出的示例不会导致递归渲染。请参阅此沙箱

不过,如果您需要将状态的初始值设置为函数返回值,setState 可以采用函数来调用其初始值:

export const MyComponent = () => {
  const [valid, setValid] = useState(externalFunction);
  // Or more verbosely:
  // const [valid, setValid] = useState(() => externalFunction());

  return <div>test</div>;
};

The example as given does not cause a recursive render. See this sandbox.

If you need to set the initial value of a state to a function return value, though, setState can take a function to call for its initial value:

export const MyComponent = () => {
  const [valid, setValid] = useState(externalFunction);
  // Or more verbosely:
  // const [valid, setValid] = useState(() => externalFunction());

  return <div>test</div>;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文