Reactjs 反应用户身份验证的错误边界(使用redux)——为什么需要本地设置状态?

Reactjs 反应用户身份验证的错误边界(使用redux)——为什么需要本地设置状态?,reactjs,error-handling,redux,higher-order-functions,Reactjs,Error Handling,Redux,Higher Order Functions,问题 我正在尝试使用阻止未登录用户的内容 我有一个“有效”的解决方案,但我不明白为什么我的黑客让它起作用。有人能帮我解开我做错了什么吗 我在做什么的一般理论 据我所知 我的应用程序中有一个组件,它封装了主内容块(而不是主导航)。它使用componentDidCatch捕获抛出的任何accessDenied并将用户重定向到登录屏幕 我有一个HOC,任何容器都可以使用它将自己限制为只登录用户。它检查存储中isAuthenticated的当前状态,如果未验证,则会将用户重定向到登录页面 如果尝试转到受

问题

我正在尝试使用阻止未登录用户的内容

我有一个“有效”的解决方案,但我不明白为什么我的黑客让它起作用。有人能帮我解开我做错了什么吗

我在做什么的一般理论 据我所知

我的应用程序中有一个组件,它封装了主内容块(而不是主导航)。它使用
componentDidCatch
捕获抛出的任何
accessDenied
并将用户重定向到登录屏幕

我有一个HOC,任何容器都可以使用它将自己限制为只登录用户。它检查存储中
isAuthenticated
的当前状态,如果未验证,则会将用户重定向到登录页面

如果尝试转到受限页面,HOC(
EnsureAuthenticatedConnector
)会抛出一个错误,该错误会冒出气泡并被
AuthBarrier
捕获

有什么问题吗?

正如下面显示的代码,这是可行的。但是我在
AuthBarrier
上设置了一个本地状态。它什么也不做

如果我删除
this.setState({hasError:true}),它会断开

URL改变,导航栏呈现(在错误边界之外),但主屏幕只是白色的

登录页面从未出现。
setState
在做什么,它没有被使用

我的代码 AuthBoundary.js——第1部分身份验证检查功能

My HOC需要一个组件,然而,
connect
也需要一个组件,它们都是函数()。为了解决这个问题,我们将它们与connect结合起来

确保必须首先使用AuthenticatedConnector
(因为我们需要它访问道具,而不是元素及其包装),因此我们有一个双箭头函数,因此它可以访问组件和道具(这是我最不清楚的部分)

RestrictedPage.js

import { connectedEnsureAuth} from "components/AuthBoundary";

const RestrictedPage = () => {
    return (
        <div>
            <h1>This content is TOP SECRET</h1>
        </div>
    );
};

RestrictedPage.displayName = "RestrictedPage";

const AuthRestrictedPage = connectedEnsureAuth(RestrictedPage);

export default AuthRestrictedPage;
从“components/AuthBoundary”导入{ConnectedSureAuth};
const RestrictedPage=()=>{
返回(
这个内容是绝密的
);
};
RestrictedPage.displayName=“RestrictedPage”;
const AuthRestrictedPage=ConnectedSureAuth(RestrictedPage);
导出默认AuthRestrictedPage;
完整的控制台错误日志

import { connectedEnsureAuth} from "components/AuthBoundary";

const RestrictedPage = () => {
    return (
        <div>
            <h1>This content is TOP SECRET</h1>
        </div>
    );
};

RestrictedPage.displayName = "RestrictedPage";

const AuthRestrictedPage = connectedEnsureAuth(RestrictedPage);

export default AuthRestrictedPage;
完全渲染时的控制台日志。

setState
remove时,以下行也会触发:
警告:AuthBarrier:错误边界应实现getDerivedStateFromError()。在该方法中,返回状态更新以显示错误消息或回退UI。

相关模块

import { connectedEnsureAuth} from "components/AuthBoundary";

const RestrictedPage = () => {
    return (
        <div>
            <h1>This content is TOP SECRET</h1>
        </div>
    );
};

RestrictedPage.displayName = "RestrictedPage";

const AuthRestrictedPage = connectedEnsureAuth(RestrictedPage);

export default AuthRestrictedPage;
  • “反应”:“^16.7.0”
  • “react redux”:“^6.0.0”
  • “反应路由器”:“^4.3.1”
  • “已连接的路由器”:“^6.2.2”

    • 引入错误边界的唯一目的是:这样应用程序在抛出错误时不会中断,对吗

      从文档中:

      如果类组件定义了生命周期方法
      static getDerivedStateFromError()
      componentDidCatch()
      中的一种(或两种)方法,则类组件将成为错误边界。使用静态getDerivedStateFromError()
在抛出错误后呈现回退UI。使用
componentDidCatch()
记录错误信息

所以想法很简单:
getDerivedStateFromError
是一个静态函数,返回状态更新

为什么??因为如果在遇到错误后不更新状态,则无法判断错误边界的呈现方法是否知道“是时候呈现一些回退UI了”
。同样,错误边界的目的是处理抛出的错误。因此,当没有状态更新时,就无法正确地知道错误边界。因此错误会传播

如果错误边界未能尝试呈现错误消息,则错误将传播到其上方最近的错误边界

在您的示例中,您没有使用
getDerivedStateFromError
,而是使用
componentDidCatch
。在该函数中,您可能已将用户发送到另一个页面(这是您处理错误的方式)。但是,除非您手动设置状态(应该使用
getDerivedStateFromError
),否则无法判断您的错误边界“已经处理了此错误,它不应该超出任何上限

我们知道错误传播时会发生什么,并且没有人处理它:

从React 16开始,未被任何错误边界捕获的错误将导致卸载整个React组件树

这就是为什么你的“主屏幕是白色的”


希望这有帮助

为什么我们需要在
静态getDerivedStateFromError
中设置状态?我还可以在
componentDidCatch
中设置状态,然后,我可以呈现一个回退组件。您也可以这样做。问题是为什么国家改变很重要,而不是在哪里。是的,我知道问题是什么。实际上,React建议设置状态应该在
静态getDerivedStateFromError
中完成,并且
componentDidCatch
应该只记录错误,因为将来您不能在其中设置状态。