取消useEffect清理功能中的所有订阅和异步任务

时间:2019-11-21 00:14:24

标签: reactjs

我有这个钩子:

export const authenticationReducer = (
  state: { busy: boolean; isAuthenticated: boolean },
  action: AuthenticatedActions
) => {
  switch (action.type) {
    case AuthenticatedActionTypes.SetIsAuthenticated: {
      return { ...action.payload };
    }
    case AuthenticatedActionTypes.SetBusy: {
      return { ...state, busy: action.payload.busy };
    }
    default:
      throw new Error(`no case for ${action} in AuthenticationReducer`);
  }
};

export const useIsUserAuthenticated = () => {
  const [{ busy, isAuthenticated }, dispatch] = useReducer(
    authenticationReducer,
    initialState
  ) as any;

  useEffect(() => {
    let isSubscribed = true;
    (async () => {
      try {
        console.log({ isSubscribed });
        dispatch(setBusy(true));

        const currentSession = await fakeApi();
        const isAuthenticated = !!(currentSession && currentSession.isValid);

        isSubscribed && dispatch(setIsAuthenticated(isAuthenticated));
      } catch (err) {
        console.error(err);
        isSubscribed && dispatch(setIsAuthenticated(false));
      }
    })();

    return () => {
      isSubscribed = false;
    };
  }, [dispatch]);

  return { busy, isAuthenticated };
};

我不得不破解一个isSubscribed局部变量,在分发前我都检查了这些变量

isSubscribed && dispatch(setIsAuthenticated(isAuthenticated));

我必须从useEffect返回,否则会收到此错误:

  

取消useEffect清理功能中的所有订阅和异步任务

该钩子的用法如下:

从“ react”导入React; 从“ react-router-dom”导入{重定向}; 从“ ./useIsUserAuthenticated”导入{useIsUserAuthenticated};

export interface AuthenticationContainerProps {
  redirectTo: string;
}

export const AuthenticatedContainer: React.FC<AuthenticationContainerProps> = ({
  children,
  redirectTo
}) => {
  const { busy, isAuthenticated } = useIsUserAuthenticated();

  if (busy) {
    return <h1>Busyyyyyy</h1>;
  }

  return isAuthenticated ? <>{children}</> : <Redirect to={redirectTo} />;
};

我真的不喜欢这种黑客手段,但是想不出更好的方法。

我创建了一个codesandbox来说明问题,但似乎并没有在codeandbox中发生,但在实际应用程序中确实发生了。

这看起来很糟糕,有更好的方法吗?

0 个答案:

没有答案