React - useEffect 与异步 setState 导致额外的重新渲染

Chr*_*hen 5 promise reactjs react-hooks

我这里有一个 React 钩子

export const useConfigDetails = (resourceName: string) => {
  const [isLoading, setLoading] = React.useState<boolean>(true);
  const [error, setError] = React.useState<AxiosError>(undefined);
  const [allEnvDetails, setAllEnvDetails] = React.useState<ResourceDetails[]>();


  React.useEffect(() => {
   const configPromises = ['dev', 'stage', 'prod'].map((environment: Environment) =>
    axios.get('someUrlGetEndpoint'));

    Promise.all(configPromises)
      .then((resp: ResourceDetails[]) => setAllEnvDetails(resp))
      .catch((err: AxiosError) => setError(err))
      .finally(() => setLoading(false));
  }, [resourceName]);

  return { allEnvDetails, isLoading };
};
Run Code Online (Sandbox Code Playgroud)

我想要实现的目标 - 每当resourceName发生更改时,它都需要刷新并调用所有不同的环境 ( dev, stage and prod),并返回最新的allEnvDetails。它应该避免其他重新渲染

理想情况下,axios.get对应于 3 个环境的调用应该只有 3个。但是,它被调用了 9 次(每个环境调用 3 次)。

根据this SO question,我在promise resolve/reject块中使用setState,因此每当功能组件(我的钩子)中的状态更新时,它都会触发另一个不需要的重新渲染。

有没有更好的方法来重构/解决这个问题?我一直在寻找一段时间,但我不确定可以改进什么。

小智 0

您可以尝试在函数开头添加条件 if(isLoading) :

`
React.useEffect(() => {
if(isLoading){
const configPromises = ['dev', 'stage', 'prod'].map((environment: 
Environment) =>
axios.get('someUrlGetEndpoint'));

Promise.all(configPromises)
  .then((resp: ResourceDetails[]) => setAllEnvDetails(resp))
  .catch((err: AxiosError) => setError(err))
  .finally(() => setLoading(false));
}
}, [resourceName]);
Run Code Online (Sandbox Code Playgroud)

`