组件上的 setState 导致无限循环

A setState on a component causes an infinite loop

我的 App.js 导致无限循环:

function App() {
  const [sessionUuid, setSessionUuid] = useState('')

  return (
    <div className="App">
      <Header setSessionUuid={setSessionUuid}/>
      <Routes>
        <Route path='/about' element={<About />} />
        <Route path="/" element={<Home />} />
        <Route path="/wine" element={<Wine sessionUuid={sessionUuid} />} />
      </Routes>
      <Footer />
    </div>
  );
}

Header 组件显示 loginlogout 按钮,具体取决于用户是否已登录。只有当用户登录或注销时,组件才会触发 setSessionUuid 函数。

    useEffect(() => {
        if (user !== '')
            setSessionUuid(user.sessionUuid)
        else
            setSessionUuid('')
    }, [user, setSessionUuid])

这会导致 App 组件无限渲染。

我在 Whosebug 上找到了这个解决方法,将 setSessionUuid 函数包装在 wrapperSetParentState = useCallback 函数中,然后将 wrapperSetParentState 传递给登录组件。但是并没有解决问题,无限渲染依旧

  const wrapperSetParentState = useCallback(val => {
    setSessionUuid(val);
  }, [setSessionUuid]);

我想要实现的是,只有路由 wine 上的组件会根据 sessionUuid

的值进行不同的渲染

setSeesionUuid 导致 useEffect 永远循环。 您可以将其从依赖项数组中删除。

useEffect(() => {
        if (user !== '')
            setSessionUuid(user.sessionUuid)
        else
            setSessionUuid('')
    }, [user])

如果 eslint 给您警告,请添加 //eslint-disable-next-line

  • setSessionUuid 不应更改并再次导致效果 运行 但根据我最近项目的经验,可以从 useEffect Deps 数组中省略 setState 函数。依赖项中需要用户,因为它可能会更改并成为不同的值。

一直是一场噩梦,但我解决了它,我想与所有相关人员分享错误所在。

首先,我创建了一个沙箱,您可以在 https://codesandbox.io/s/bitter-water-jsblw?file=/src/App.js:367-374 访问它:如您所见,它 运行 很有魅力 ;-) 不需要奇怪的东西,useEffects或其他不必要的东西。

所以,错误不可能存在。

然后,我删除了 my App.js 中唯一的东西,而不是沙盒中的东西。我没有在最初的消息中插入它,因为......它已经在那里几个月没有问题而且对我来说是完全看不见的:任何看不见的东西都会造成问题吗?是的,它可以!

指令是

const langs = navigator.languages;  //["en-US", "zh-CN", "ja-JP"] 
const userLanguageCode = langs[0].length > 2 ? langs[0].substring(0, 2) : langs;
i18n.changeLanguage(userLanguageCode);

而且,准确地说,是 i18n.changeLanguage(userLanguageCode); 造成了问题。我删除了它,所有内容 运行 都完美无缺,就像在沙盒中一样。

感谢大家的支持,希望这次的不幸经历能给大家带来思考。

再次感谢您