React功能组件中的“超出最大更新深度”

时间:2019-05-27 22:38:30

标签: reactjs

我对React功能组件有问题。当react-apollo查询“完成时”执行代码以处理令牌,并在完成时发送到另一页(使用history.push)。

运行代码时,出现以下消息,发生无限循环:Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops

  1. 我尝试评论history.push,并且无限循环不会再发生。

  2. 我注释了list-session组件中的所有逻辑,以避免进行递归调用,但是它不起作用(我彻底检查了代码以确认不是递归调用)。

我认为问题与生命周期或历史记录有关。push行为

Ptt:我正在学习这一刻的反应

  const { setUserInfo, setUserId } = useContext(userContext);
  const { token } = match.params;

  const onCompleted = data => {
    if (data.validateUser.status) {
      setUserId(token);
      setUserInfo(data.validateUser.infoUser);
      localStorage.setItem("token", token);
      // history.push("/list-session");
    } else {
      history.push("/rare-page");
    }
  };

  return (
    <div className="Auth" data-testid="AuthPage">
      <Query
        query={VALIDATE_USER}
        variables={{ userId: token }}
        onCompleted={onCompleted}
      >
        {({ error }) => {
          if (error) return <Error />;
          return (
            <>
              <h2 data-testid="AuthState">Authenticating...</h2>
              <div className="spinner-border text-info" role="status">
                <span className="sr-only">Loading...</span>
              </div>
            </>
          );
        }}
      </Query>
    </div>
  );
}

编辑1: 在问题中添加了相关代码。我检查了组件,没有一个进行递归调用,也没有进行无限的 setState 调用。 setState 问题是另一个问题的隐患。

        <AnimatedSwitch
          atEnter={bounceTransition.atEnter}
          atLeave={bounceTransition.atLeave}
          atActive={bounceTransition.atActive}
          mapStyles={mapStyles}
          className="route-wrapper"
        >
          <Route exact path="/" component={NoCredentials} />
          <Route exact path="/token/:token" component={Auth} />
          <Route path="/list-session" component={Home} />
        </AnimatedSwitch>

这是Home组件中的代码:

const Home = () => {
  const [activeTab, setActiveTab] = useState("activeSessions");

  return (
    <ValidateToken>
      <Container className="bg-light">
        <div className="Home">
          <CreateSessionComponent />
          <Nav tabs>
            <NavItem>
              <NavLink
                className={classnames({
                  active: activeTab === "activeSessions"
                })}
                onClick={() => setActiveTab("activeSessions")}
              >
                Active Sessions
              </NavLink>
            </NavItem>
          </Nav>
          <TabContent activeTab={activeTab}>
            <TabPane tabId="activeSessions">
              {activeTab === "activeSessions" && (
                <div>
                  <SessionsListComponent status="ACTIVE" />
                </div>
              )}
            </TabPane>
          </TabPane>
          </TabContent>
        </div>
      </Container>
    </ValidateToken>
  );
};

export default Home;

2 个答案:

答案 0 :(得分:0)

当您尝试多次更新变量直到堆栈大小超出时,发生“超出最大更新深度”错误。当您试图在render()内设置状态或在render内调用方法来设置状态时,通常会发生这种情况。因此,请检查代码的render方法中是否存在setState()调用。
由于在render中设置了localStorage变量,因此也可能发生这种情况。尝试将其移出渲染。但是,如果您仍然需要它,可以使用componentDidMount()钩子。这样,在渲染组件时,所有变量都将对您可用。

答案 1 :(得分:0)

尝试一下,我认为它可能会起作用。

<Query
  query={VALIDATE_USER}
  variables={{ userId: token }}
  onCompleted={(e)=>onCompleted(e)} //onCompleted throws an event
>