代码之家  ›  专栏  ›  技术社区  ›  user3142695

ReactJS:如何在父组件中显示子组件错误

  •  3
  • user3142695  · 技术社区  · 7 年前

    如果子元素上发生错误,我希望在父组件上显示错误消息。

    在这种情况下,一个错误可能是捕获了apollo突变调用,例如,您可以在孙子组件中看到。

    当然,我可以在父组件中创建一个函数,为错误设置一个状态值,并将该函数传递给每个子组件、孙子组件等等。 但由于我的结构有点复杂,这将意味着大量的工作。这就是为什么我想到使用react错误边界。但这是正确的用例吗?

    当我使用nextJS时,每个 throw Error 将在开发模式下显示错误堆栈跟踪,因此无法将错误显示为消息

    Parent.js

    export class Parent extends Component {
      render () {
        return (
          { /* if there is an error in any child component, it should be displayed here */
            this.props.error &&
            <Message>{error}</Message>
          }
          <Child {...props} />
        )
      }
    }
    

    class GrandChild extends Component {
      doAnything () {
        return this.props.assumeToFail({
          variables: { id: '123' }
        }).catch(error => {
          console.error(error) // <-- this error should be given back to parent
          throw new Error('fail') // <-- should I throw the error or call a custom function?
        })
      }
    
      render () {
        return (
          <Button onClick={this.doAnything().bind(this)}>anything</Button>
        )
      }
    }
    
    export default graphql(exampleMutation, { name: 'assumeToFail' })(GrandChild)
    

    要在我的nextJS应用程序中使用错误边界,我只需添加

    _app.js

    class MyApp extends App {
      componentDidCatch (error, errorInfo) {
        console.log('CUSTOM ERROR HANDLING', error)
        // How do I get the error down to 'Component' in render()?
        super.componentDidCatch(error, errorInfo)
      }
    
      render () {
        const { Component, pageProps, apolloClient } = this.props
        return <Container>
          <ApolloProvider client={apolloClient}>
            <Component {...pageProps} />
          </ApolloProvider>
        </Container>
      }
    }
    

    _app.js Component

    1 回复  |  直到 7 年前
        1
  •  1
  •   GabLeRoux Tidder Jail    6 年前
    1. 实现这一点的最佳方法是使用react状态管理,如 redux fluxible 如果您使用的是react状态管理,则可以通过从 child.js 并连接到中的redux存储 parent.js 以轻松获取错误消息。

    2. 如果您决定使用您所描述的函数,您可以将函数传递给子函数,并让子函数调用该函数。

    Parent.js

    export class Parent extends Component {
      state = {
        error: null,
      }
    
      render () {
        return (
          { /* if there is an error in any child component, it should be displayed here */
            this.state.error &&
            <Message>{this.state.error}</Message>
          }
          <Child
            {...props}
            defineError={(errMsg) => setState({ error: errMsg })}
          />
        )
      }
    }

    import PropTypes from 'prop-types';
    
    class GrandChild extends Component {
      static propTypes = {
        defineError: PropTypes.func,    
      }
    
      doAnything () {
        return this.props.assumeToFail({
          variables: { id: '123' }
        }).catch(error => {
          this.props.defineError(error);
          console.error(error) // <-- this error should be given back to parent
          throw new Error('fail') // <-- should I throw the error or call a custom function?
        })
      }
    
      render () {
        return (
          <Button onClick={this.doAnything().bind(this)}>anything</Button>
        )
      }
    }
    
    export default graphql(exampleMutation, { name: 'assumeToFail' })(GrandChild)