【问题标题】:React render - Infinite loop happenes sometimesReact 渲染 - 有时会发生无限循环
【发布时间】:2021-12-06 04:15:43
【问题描述】:

我有一个简单的登录组件,它工作正常(即在成功登录后大部分时间它都会重定向到仪表板)。但是,有时会出乎意料地抛出错误:

错误:超过最大更新深度。这可能发生在组件 在 componentWillUpdate 内重复调用 setState 或 组件更新。 React 将嵌套更新的数量限制为 防止无限循环。

这是我的代码。 请注意,当错误发生时,我注意到 <Redirect to={routes.DASHBOARD}/> 这被调用,但不是重定向到该组件,而是相同的登录组件不断被无限调用。

import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Redirect } from 'react-router';
import { login } from '../../redux/actions';
import styles from './login.module.css';
import {routes} from '../../routes';

export function Login() {
  const { user } = useSelector((state) => state);
  const dispatch = useDispatch();

  const [email, setEmail] =useState('');
  const [password, setPassword] = useState('');
  const handleLogin = ()=>{
      dispatch(login({email, password}))
  }

  const handleEmailInput = (e)=>{
      setEmail(e.target.value)
  }

  const handlePasswordInput = (e)=>{
      setPassword(e.target.value)
  }

  if((user.tokenReceived || localStorage.getItem('token')) && !user.tokenExpired){
    return <Redirect to={routes.DASHBOARD}/>
  }

  return (
    <div>
      <div className={styles.row}>

          <input type='text' placeholder="Email" onChange={handleEmailInput}/>
          <input type='text' placeholder="Password" onChange={handlePasswordInput}/>

        <button
          className={styles.loginButton}
          onClick={handleLogin}
        >
          Login
        </button>
        {user.error && "Some Error occurred. Please try again"}
      </div>
    </div>
  );
}

我很确定我的做法是正确的,但我是否应该将其包装在 useEffect 下,

if((user.tokenReceived || localStorage.getItem('token')) && !user.tokenExpired){
    return <Redirect to={routes.DASHBOARD}/>
  } 

【问题讨论】:

  • 您能提供您的登录操作代码吗?
  • @MarioNikolaus 我不想让它太冗长,所以没有放在这里。但如果这与您相关,您可以在这里查看:github.com/wickedrahul/react-app-gateway/blob/main/my-app/src/…
  • 看了你的代码之后。您有 2 个事实来源来检查登录。因此,如果令牌未正确保存在 localStorage 中,您的仪表板将返回登录,因为您只检查 localStorage 令牌。在登录页面上,您可以从商店或本地存储中接受。所以想象一下你的 redux 存储中有令牌但没有保存在 localStorage 中的情况。登录组件将重定向到仪表板,反之亦然。我会先检查一下
  • @MarioNikolaus 发现错误。实际发生的是,Login 组件重定向到 Dashbboard,但是,在 App.js 中,它检查用户是否经过身份验证(通过查看本地存储)。此时localstorage没有设置。因此,App.js 重定向回 Login 并且来回继续。这也解释了为什么重定向到仪表板没有发生唷!很讨厌的一个。感谢您的投入。如果您愿意将此作为答案,我会投票。
  • 不用了,我根本没检查App代码!很好,你找到了。但是,是的,通常单一的事实来源是简化生活的一种方式:D

标签: javascript reactjs react-hooks redux-toolkit


【解决方案1】:

我认为您的问题在于您在单击按钮时调用 handleLogin 函数。将该函数作为箭头函数调用。

<button
     className={styles.loginButton}
     onClick={() => handleLogin()}
>

【讨论】:

  • handleLogin 本身就是一个回调,所以我不明白为什么会出现这个问题。
【解决方案2】:

每次更新状态时,页面都会重新呈现。这意味着每次更新状态时,都会调用这个if

当用户刚刚访问页面时,使用 UseEffect 来验证数据。

useEffect(() => {
  if((user.tokenReceived || localStorage.getItem('token')) && !user.tokenExpired){
    return <Redirect to={routes.DASHBOARD}/>
  } 
}, [])

【讨论】:

    猜你喜欢
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    • 2023-03-08
    相关资源
    最近更新 更多