3

我使用 React 16功能Error Boundary:Profile.js

class Profile extends Component {
constructor(props) {
    super(props);
    this.state = {
        // user: {
        //     name: "Ha (Huck) H.K. NGUYEN"
        // }
        user: null
    };
    this.updateUser = this.updateUser.bind(this);
}

updateUser() {
    this.setState({ user: null })
}

render() {
    const { user } = this.state;
    console.log(user);
    return <div className="App">
            {user.name}
            <button onClick={this.updateUser}>
                Update
            </button>
        </div>
}
}

错误边界.js

class ErrorBoundary extends Component {
constructor(props) {
    super(props);
    this.state = {
        hasError: false
    }
}
componentDidCatch(error, errorInfo) {
    this.setState({ hasError: true });
}
render() {
    const { children } = this.props;
    const { hasError } = this.state;
    if (hasError) {
        return <HasError />
    }
    return children
}
}

应用程序.js

class App extends Component {
render() {
    return <div className="App">
    <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <h1 className="App-title">Welcome to React</h1>
    </header>
    <ErrorBoundary>
        <Profile />
    </ErrorBoundary>
</div>
}
}

我看到功能组件在错误发生并被捕获后仍然被调用。谁能解释一下为什么render调用该函数。 在此处输入图像描述

对于不知道的人,请按照链接中的答案,您可以通过按键查看错误边界esc

4

3 回答 3

2

正如您在问题中已经提到的那样,按下Esc取消覆盖,您可以看到ErrorBoundary消息并且覆盖的可见性仅限于开发环境。

你可以在这里查看更多信息

但是关于为什么要执行渲染函数,你需要知道一旦render函数被执行并且你的代码抛出了一个 RuntimeError ,componentDidCatch你的ErrorBoundary. 还有create-react-app一个功能,它可以侦听RuntimeErrors正在生成的内容,并报告错误的根本原因,这就是您在叠加层中看到的内容。

要检查产生 Overlay 的相关代码,您可以查看这个github 代码

我希望我能够回答你的问题。

于 2018-07-23T16:46:11.500 回答
1

https://codesandbox.io/s/nn9kw2k3ql

这是一个工作示例,您需要按esc

我在Profile没有改变任何东西的情况下放入你的,它也按预期工作。

只是要清楚...

esc一旦您进入生产设置,您可以单击的红色叠加层将被删除。它们仅供开发使用。这就是为什么您要实现errorBoundary在这两种情况下都可以使用的原因。

因此,如果您的代码在开发过程中出现错误,这两个错误都会出现。

如果您查看控制台,您会收到以下消息:

false // from ErrorBoundary this.state.error
i am here  // inside the potential error componenet
i am here  // inside the potential error componenet
The above error occurred in the <Profile> component: //from Error Boundary
true // from ErrorBoundary this.state. error

第一个 false 来自 ErrorBoundary,因为在初始加载时,没有错误,所以它会尝试渲染children,然后它会登录i am here孩子。发现错误,更新errorboundary组件。之后,你就再也看不到I am here了,因为errorboundary踢进去了,不再渲染children

为了errorBoundary知道其中有一些错误children,必须首先发生错误。否则它不知道。JS 是一个动态类型的语言,一切都需要在运行时发生。

于 2018-07-23T02:47:25.750 回答
1

我认为你有一个错误的条件如下:

if (!hasError) {
        return <HasError />
    }

如果 hasError 为真,你想在这里显示错误,对吧?否则将呈现 Profile 组件。

而且 componentDidCatch 内置在 react16 中,所以如果渲染函数抛出任何错误,这个方法将被自动触发。

于 2018-07-23T02:51:34.700 回答