首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >依赖API响应的SetState导致了太多的重呈现错误。

依赖API响应的SetState导致了太多的重呈现错误。
EN

Stack Overflow用户
提问于 2021-12-15 09:25:37
回答 1查看 109关注 0票数 0

在下面的代码中,我试图将stop的状态设置为true,以便在从特定API到useQuery的响应中,基于特定的代码,我可以开始轮询API。默认情况下,轮询仍然是假的。

我的问题是,如何在这里设置状态,而不引发Too many re-renders error

问题档案

代码语言:javascript
复制
import React, { useState } from 'react';
import { Navigate, useLocation } from 'react-router-dom';
import { useBffQueryApi } from '../hooks/useQueryBffApi';
import {
  appStatus,
  IStatusAPIResponse,
  IHeaderInformation,
} from '../api/appStatus';
import { useAppSelector } from '../app/hooks';
import { RootState } from '../app/store';
// import { MobileNumber } from './features/ContactNumber/MobileNumber';

export function web() {
  const location = useLocation();
  const authzToken = useAppSelector(
    (state: RootState) => state.authz.AuthzInfo,
  );

  const [stop, setStop] = useState(true);

  const {
    data: response,
    error,
    isLoading,
  } = useBffQueryApi<IStatusAPIResponse, IHeaderInformation>(
    'status',
    () => appStatus({ auth: authzToken }),
    true,
    stop,
  );

  const redirecter = (status: number) => {

//Here lies the problem

    if (status === 306) {
      setStop(false);
      // Do something
    }

//Here lies the problem

    if (status === 41) {
      return <Navigate to="/web/email-confirmation" />;
    }

    if (status === 42) {
      return <Navigate to="/web/personal-details" />;
    }

    if (status === 44) {
      return <Navigate to="/web/address-details" />;
    }

    if (status === 50) {
      return <Navigate to="/web/offer-details" />;
    }

    if (status === 48) {
      return <Navigate to="/web/denied" />;
    }

    if (status === 51 || status === 52 || status === 53) {
      return <Navigate to="/web/offer-details" />;
    }

    if (status === 46) {
      return (
        <Navigate
          to="/web/third-party"
          state={{ location: location.pathname }}
        />
      );
    }

    if (status === 47) {
      return <Navigate to="/web/third-party" />;
    }

    return null;
  };

  if (isLoading) {
    return (
      <div>
        <h1>Loading</h1>
      </div>
    );
  }

  if (error?.response?.status === 401) {
    return <Navigate to="/web/phone" />;
  }

  const { status } = response!.data;

  return redirecter(status);
}

定制钩

代码语言:javascript
复制
import { AxiosError, AxiosResponse } from 'axios';

export const useBffQueryApi = <J, K>(
  cacheIdentity: string | Array<string | K>,
  fn: QueryFunction<AxiosResponse<J>>,
  enabled: boolean = true,
  stop: boolean = true,
) => {
  return useQuery<AxiosResponse<J>, AxiosError>(cacheIdentity, fn, {
    retry: 0,
    cacheTime: 0,
    enabled,
    refetchInterval: stop ? false : 5000,
  });
};
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-15 15:05:29

您不能在呈现期间调用setState,这违反了react规则。你在这里做的是:

代码语言:javascript
复制
if (status === 306) {
  setStop(false);
  // Do something
}

副作用需要转到useEffect,或者,您可以使用useQuery提供的onSuccessonError回调。

对于您的情况,您不一定需要本地状态,因为refetchInterval也可以是一个函数:

代码语言:javascript
复制
useQuery(
  key,
  fn,
  {
    refetchInterval: (data) => !data || data.status === 306 ? false : 5000
  }
)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70361184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档