Javascript ReactJS:如何在父组件中显示子组件错误
如果子元素上发生错误,我希望在父组件上显示错误消息 在这种情况下,一个错误可能是捕获了apollo突变调用,例如,您可以在孙子组件中看到 当然,我可以在父组件中创建一个函数,为错误设置一个状态值,并将该函数传递给每个子组件、孙子组件等等。 但由于我的结构有点复杂,这将意味着大量的工作。这就是为什么我想到使用react错误边界。但这是正确的用例吗 当我使用nextJS时,每个Javascript ReactJS:如何在父组件中显示子组件错误,javascript,reactjs,next.js,Javascript,Reactjs,Next.js,如果子元素上发生错误,我希望在父组件上显示错误消息 在这种情况下,一个错误可能是捕获了apollo突变调用,例如,您可以在孙子组件中看到 当然,我可以在父组件中创建一个函数,为错误设置一个状态值,并将该函数传递给每个子组件、孙子组件等等。 但由于我的结构有点复杂,这将意味着大量的工作。这就是为什么我想到使用react错误边界。但这是正确的用例吗 当我使用nextJS时,每个抛出错误都会在开发模式下显示错误堆栈跟踪,因此不可能将错误显示为消息 Parent.js export class Pare
抛出错误
都会在开发模式下显示错误堆栈跟踪,因此不可能将错误显示为消息
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)
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>
}
}
导出类父级扩展组件{
渲染(){
返回(
{/*如果任何子组件中存在错误,则应在此处显示*/
这是一个错误&&
{错误}
}
)
}
}
孙子.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)
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>
}
}
类孙子扩展组件{
做任何事(){
返回此.props.assumeToFail({
变量:{id:'123'}
}).catch(错误=>{
控制台。错误(错误)//
实现这一点的最佳方法是使用反应状态管理,如或。
如果您使用的是react状态管理,那么您可以通过从child.js
发送消息并连接到parent.js
中的redux存储来调用操作,以轻松获取错误消息
如果您决定使用您所描述的函数,您可以将函数传递给子函数,并让子函数调用该函数
Parent.js
导出类父级扩展组件{
状态={
错误:null,
}
渲染(){
返回(
{/*如果任何子组件中存在错误,则应在此处显示*/
这个。状态。错误&&
{this.state.error}
}
setState({error:errMsg})}
/>
)
}
}
请看componentDidCatch
@quirimmo请看更新后的帖子:我在我的nextJS应用程序中使用componentDidCatch
,但这会导致总是在开发模式下显示stacktrace,因此我无法显示组件中的错误。请阅读我共享的链接。他们谈到了这一点too@quirimmo在nextJS中,stacktrace未打开该应用程序被直接传递到控制台,但也显示在屏幕上。因此,如果出现错误,应用程序将不再可见(在开发模式下)componentDidCatch
只是其中的一部分,您还需要创建一个实现componentDidCatch
的错误边界组件,以便它可以返回一些错误状态,并在此基础上返回一个回退组件。请参阅。请注意,它确实会转储一个全屏堆栈跟踪“model”,其中有一个“X”在右上角关闭它并返回应用程序。React提供了一种默认方法来处理来自任何渲染子体(而不仅仅是直接子体)的错误通过错误边界,如果需要,您还可以通过生命周期功能对正在使用的任何redux或应用程序状态进行更新。无需重新发明控制盘。React的错误边界与链上最近边界(catch)处理错误的try/catch
块类似。