Javascript 什么';getDerivedStateFromError和componentDidCatch之间的区别是什么

Javascript 什么';getDerivedStateFromError和componentDidCatch之间的区别是什么,javascript,reactjs,Javascript,Reactjs,我从中了解到: 组件DIDCATCH: 始终在浏览器中调用 在DOM已更新的“提交阶段”期间调用 应该用于类似错误报告的内容 getDerivedStateFromError: 在服务器端渲染期间也调用 当DOM尚未更新时,在“渲染阶段”调用 应用于呈现回退UI 尽管如此,我还是对一些事情感到困惑: 它们是否都捕获相同类型的错误?或每个生命周期 将捕获不同的错误吗 我是否应该始终使用这两种方法(可能在同一个“错误捕获”组件中) “使用componentDidCatch进行错误恢复并非最佳

我从中了解到:

组件DIDCATCH

  • 始终在浏览器中调用
  • 在DOM已更新的“提交阶段”期间调用
  • 应该用于类似错误报告的内容
getDerivedStateFromError

  • 在服务器端渲染期间也调用
  • 当DOM尚未更新时,在“渲染阶段”调用
  • 应用于呈现回退UI
尽管如此,我还是对一些事情感到困惑:

  • 它们是否都捕获相同类型的错误?或每个生命周期 将捕获不同的错误吗
  • 我是否应该始终使用这两种方法(可能在同一个“错误捕获”组件中)

  • “使用componentDidCatch进行错误恢复并非最佳选择,因为它会强制回退UI始终同步呈现”这有什么问题

  • 当呈现过程中、生命周期方法中或任何子组件的构造函数中出现错误时,将调用这两种方法。它们可以在实现错误边界时使用

    根据

    getDerivedStateFromError
    在子组件抛出错误后调用生命周期。它接收作为参数抛出的错误,并应返回值以更新状态


    它们是否都捕获相同类型的错误?或者每个生命周期都将 抓住不同的错误

    这两个生命周期方法都将捕获相同的错误,但这两个组件的参数不同

    getDerivedStateFromError
    仅接收错误作为参数时,componentDidCatch还接收第二个参数,即
    info,即具有componentStack键的对象,其中包含有关哪个组件抛出错误的信息。

    getDerivedStateFromError()
    在“渲染”阶段被调用,因此不允许出现副作用。对于这些用例,请改用
    componentDidCatch()
    。虽然
    componentDidCatch
    也可用于设置状态,但在将来的版本中,这将被弃用

    componentDidCatch
    应用于记录错误等副作用


    另外,
    @Brian Vaughn
    在您提供的链接中详细介绍了它们的用法

    getDerivedStateFromError
    可用于服务器端渲染。
    componentDidCatch是一个提交阶段生命周期,但没有提交 服务器上的阶段。getDerivedStateFromError是一个渲染阶段 生命周期,因此它可用于在 服务器

    渲染阶段恢复更安全。通过
    componentDidCatch
    有点古怪,因为它依赖于 对于以下组件的所有内容,中间提交为“null” 出错了。这可能会导致任何 实现componentDidMount或 componentDidUpdate并假设它们的引用将是非空的 (因为它们总是在无错误的情况下)

    getDerivedStateFromError
    不强制同步渲染。因为状态从提交更新 阶段生命周期始终是同步的,因为组件没有捕获
    在提交阶段调用–使用componentDidCatch查找错误 恢复不是最佳的,因为它迫使回退UI始终 同步渲染。(无可否认,这不是什么大问题,因为 错误恢复应该是一种边缘情况。)

    如果发生错误,您的错误边界
    getDerivedStateFromError()
    方法将首先被调用(以更新 状态),然后是render()方法(实际呈现回退UI), 然后
    componentDidCatch
    (一旦将回退UI提交到 DOM)

    如果错误边界定义了其他生命周期方法(例如。 componentWillUpdate,componentDidUpdate)他们也会被调用, 就像其他渲染一样



    “使用componentDidCatch进行错误恢复不是最优的,因为 强制回退UI始终同步呈现“出了什么问题?” 用那个


    这意味着,在呈现回退UI的render方法之后调用componentDidCatch,这可能会导致更多问题,而
    getDerivedStateFromError
    会在呈现阶段之前更新状态,以便呈现正确的回退UI,并且不会对呈现的组件造成更多错误。此外,新版本的目标是异步呈现,这可能与当前方法存在问题。问题中的陈述基本上是正确的。目前SSR中不支持错误边界,
    getDerivedStateFromError
    componentDidCatch
    不会影响服务器端

    它们是否都捕获相同类型的错误?或者每个生命周期将捕获不同的错误

    他们正在捕捉相同的错误,但处于不同的阶段。这在以前仅通过
    组件didcatch
    就可以实现:

      static getDerivedStateFromError() {
        return { hasError: true };
      }
    

    做同样的事情,
    componentDidCatch
    没有机会在服务器端得到支持,除非对异步呈现的支持被添加到
    ReactDOMServer

    我是否应该始终使用这两种方法(可能在同一个“错误捕获”组件中)

    两者都可以使用。来自的示例显示:

    class ErrorBoundary extends React.Component {
      state = { hasError: false };
    
      static getDerivedStateFromError(error) {
        return { hasError: true };
      }
    
      componentDidCatch(error, info) {
        logComponentStackToMyService(info.componentStack);
      }
    
      render() {
        if (this.state.hasError) {
          return <h1>Something went wrong.</h1>;
        }
    
        return this.props.children; 
      }
    }
    
    类ErrorBoundary扩展React.Component{
    状态={hasError:false};
    静态getDerivedStateFromError(错误){
    返回{hasError:true};
    }
    componentDidCatch(错误,信息){
    logComponentStackToMyService(info.componentStack);
    }
    render(){
    if(this.state.hasError){
    返回出了问题的地方。;
    }
    返回此.props.children;
    }
    }
    
    class ErrorBoundary extends React.Component {
      state = { hasError: false };
    
      static getDerivedStateFromError(error) {
        return { hasError: true };
      }
    
      componentDidCatch(error, info) {
        logComponentStackToMyService(info.componentStack);
      }
    
      render() {
        if (this.state.hasError) {
          return <h1>Something went wrong.</h1>;
        }
    
        return this.props.children; 
      }
    }