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
应该只记录错误,因为将来您不能在其中设置状态。