代码之家  ›  专栏  ›  技术社区  ›  Dominic Woodman

用户身份验证的反应错误边界(使用redux)-引发重复的身份验证错误

  •  0
  • Dominic Woodman  · 技术社区  · 5 年前

    我试着用 React error boundaries

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

    我在做什么的一般理论

    据我所知。。。

    我有一个组件,坐在我的应用程序和包装的主要内容块(不是主导航tho)。它使用 componentDidCatch 抓住任何 accessDenied 抛出并将用户重定向到登录屏幕。

    我有一个HOC,任何容器都可以使用它来限制自己只允许登录用户。它检查 isAuthenticated

    如果您尝试转到受限页面,则( EnsureAuthenticatedConnector )抛出一个错误,该错误冒出气泡并被 AuthBarrier .

    有什么问题吗?

    AuthBarrier公司 . 它什么也不做。

    如果我移除 this.setState({ hasError: true }); ,它断了。

    URL改变,navbar呈现(在错误边界之外),但是主屏幕是白色的。

    setState 做什么,没用吗?

    我的代码

    AuthBoundary.js—第1部分身份验证检查函数

    connect ref ). 为了解决这个问题,我们将它们与connect结合起来。

    必须放在第一位(因为我们需要它访问道具,而不是元素的包装),所以我们有一个双箭头函数,所以它可以访问组件和道具(这是我最不清楚的部分)。

    const accessDenied = {};
    
    const EnsureAuthenticatedConnector = ComposedComponent => props => {
        if (!props.isAuthenticated) {
            console.log("This console fires twice, but only when an error is thrown in here.");
            throw accessDenied;
        }
        return <ComposedComponent {...props} />;
    };
    
    const mapStateToPropsEnsureAuth = state => {
        return {
            isAuthenticated: state.auth.isAuthenticated,
        };
    };
    
    const connectedEnsureAuth = compose(
        // These are both single-argument HOCs
        connect(
            mapStateToPropsEnsureAuth,
            null
        ),
        EnsureAuthenticatedConnector
    );
    
    ...
    export { ConnAuthBarrier, connectedEnsureAuth };
    

    class AuthBarrier extends Component {
        static propTypes = {
            dispatch: PropTypes.func.isRequired,
            children: PropTypes.node.isRequired
        };
    
        constructor(props) {
            super(props);
            this.state = {
                hasError: false
            };
        }
    
        // Catch child errors if they're access denied.
        componentDidCatch(error) {
            if (error === accessDenied) {
                // For reasons unknown removing this line
                // causes this to break.
                // This makes no sense, because I don't use this anywhere...
                this.setState({ hasError: true });
                this.props.dispatch(push("/login"));
            }
        }
        render() {
            // We do nothing clever always render the 
            // children
            return this.props.children;
        }
    }
    const ConnAuthBarrier = connect()(AuthBarrier);
    

    受限页面.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;
    

    enter image description here

    设置状态 删除,则以下行也会触发: Warning: AuthBarrier: Error boundaries should implement getDerivedStateFromError(). In that method, return a state update to display an error message or fallback UI.

    • “react redux”:“^6.0.0”,
    • “react路由器”:“^4.3.1”,
    • “已连接路由器”:“^6.2.2”,
    0 回复  |  直到 5 年前
        1
  •  2
  •   mehamasum    5 年前

    引入错误边界的目的只有一个:这样应用程序在抛出错误时不会中断,对吗?

    static getDerivedStateFromError() componentDidCatch() . 使用 在抛出错误后呈现回退UI。使用 componentDidCatch()


    getDerivedStateFromError 是一个返回状态更新的静态函数。

    为什么?因为如果在遇到错误后不更新状态,就无法判断错误边界的呈现方法是否知道 “是时候呈现一些回退UI了”

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

    在您的示例中,您没有使用 getDerivedStateFromError错误 ,而不是 componentDidCatch . 在该函数中,您可能已将用户发送到另一个页面(即 你的方式 getDerivedStateFromError错误 )无法判断您的错误边界 ".

    我们知道当错误传播而没有人处理时会发生什么:

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

    希望这有帮助。 Docs on Error Boundary