我正在尝试改进使用react-query
.
我有一个经过<ErrorBoundary>
身份验证的用户路由器的组件:
<ErrorBoundaryRoot errorMessage="auth error">
<PracticeTypeContextProvider>
<IonReactRouter>
... myRoutesAndStuff
组件包装器如下所示:
import { ErrorBoundary } from 'react-error-boundary';
const ErrorBoundaryRoot: React.VFC<MyProps> = ({ children, errorMessage }: MyProps) => {
const { reset } = useQueryErrorResetBoundary();
return (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<PageError errorMessage={errorMessage} resetErrorBoundary={resetErrorBoundary} />
)}
>
<Suspense fallback={<LoadingApp />}>
{ children }
</Suspense>
</ErrorBoundary>
);
};
这正确地捕获了错误,太棒了!
现在,我想向用户展示两个按钮之一:
- 如果这是第一次看到错误边界,
<ButtonInvalidateAuthQueries>
那么我可以尝试在不注销用户的情况下重置应用程序。 - 但是,如果失败了,我想向用户显示一个不同的按钮 ,
<ButtonResetApp>
它会重置所有查询并将用户注销。
我这样设置我的<PageError>
组件:
const PageError: React.VFC<MyProps> = ({ errorMessage, resetErrorBoundary }: MyProps) => {
const [alreadyTriedItOnce, setAlreadyTriedItOnce] = useState(false);
return (
<IonPage>
<IonContent>
<>
{ alreadyTriedItOnce ? (
<ButtonResetApp platform={platform} resetErrorBoundary={resetErrorBoundary} />
) : (
<ButtonInvalidateAuthQueries
setAlreadyTriedItOnce={setAlreadyTriedItOnce}
resetErrorBoundary={resetErrorBoundary}
/>
)}
</>
)}
</IonContent>
</IonPage>
);
};
和无效按钮:
const ButtonInvalidateAuthQueries: React.VFC<MyProps> = (
{ setAlreadyTriedItOnce, resetErrorBoundary }: MyProps,
) => {
const queryClient = useQueryClient();
return (
<IonButton
onClick={() => {
queryClient.invalidateQueries(queryKeyInvalidateAllAuthQueries);
resetErrorBoundary();
setAlreadyTriedItOnce(true);
}}
>
Reset auth queries
</IonButton>
);
};
但是,这不起作用,因为当用户单击 时<ButtonInvalidateAuthQueries>
,所有 auth 组件都会重新渲染,包括错误边界,因此如果再次显示错误边界,则将alreadyTriedItOnce
状态初始化为 false。
所以我的问题是:是否有一些聪明的方法来判断是否<ButtonInvalidateAuthQueries>
失败,如果是,则显示<ButtonResetApp>
?
作为一种解决方法,我可以显示两个按钮,并给用户指示“先单击这个,如果不起作用,请单击另一个”,但我觉得作为一名程序员,我的工作是为用户提供最好的在任何给定时间选择。