React 中的错误边界:为什么 'throw new Error('some message')' 失败而 'throw errorObj' 工作?

Cer*_*ean 7 javascript error-handling reactjs react-hooks

我正在学习 React 中的错误边界。我想我已经有了很好的基本理解,但是在为异步过程(例如加载数据)实现它们时遇到了麻烦。

假设我有一个简单的组件,它使用 React 钩子从远程 API 加载一些数据。由于错误边界本身不会使用异步进程工作,而不是在 中抛出错误catch,该组件存储errorinstate并在下一次重新渲染时抛出它

// MovieDb.js
import axios from "axios"
import {useEffect,useState} from 'react'

export default (query) => {

  const [movies, setMovies] = useState([])
  const [error,setError] = useState(null)

  if (error) throw error

  useEffect(() => {
    const getData = async () => {
      try {
        const results = await axios.get('https://api.themoviedb.org/3/search/movie', {
          params: {
            api_key: 'somethingsomething',
            query
          }
        })
        setMovies(results.data.results)
      } catch (e) {
       setError(e)
      }
    }
    getData()
  }, [query])

  return movies

}
Run Code Online (Sandbox Code Playgroud)

这个组件在我的应用程序中使用:

// App.js
  function App() {

  const [query, setQuery] = useState('Lord of the Rings')

  const movies = MovieDb(query)
  return (
    <div className="App">
      <SearchInput onChange={e => setQuery(e.target.value)} defaultValue={query}/>
      {movies && movies.map(movie=> <div key={movie.id}>{movie.title}</div>) }
    </div>
  );
}

export default App;
Run Code Online (Sandbox Code Playgroud)

我的错误边界很简单:

//Catch.js
import React, { Component } from 'react'

export default class Catch extends Component {
  state = { hasError: false ,error:''}

  static getDerivedStateFromError(error) {
    return { hasError: true,error }
  }

  render() {
    if (this.state.hasError) {

      return <h1>{`There was a problem: ${this.state.error.message}`}</h1>
    }

    return this.props.children
  }
}
Run Code Online (Sandbox Code Playgroud)

这个Catch组件然后包装应用程序:

// index.js
ReactDOM.render(<Catch><App/></Catch>, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)

当我在内部抛出错误时,错误边界似乎起作用MovieDb,例如在调用 API 时。然而,当我改变

 if (error) throw error
Run Code Online (Sandbox Code Playgroud)

 if (error) throw new Error('some message')
Run Code Online (Sandbox Code Playgroud)

或者

 if (error) throw new Error(error.message)
Run Code Online (Sandbox Code Playgroud)

错误边界不起作用,应用程序崩溃。为什么是这样?我问是为了让我能更好地理解我在做什么,而不仅仅是为了让它发挥作用。谢谢你的帮助!

小智 6

这是开发环境的产物。您可以通过点击“escape”或“X”来关闭堆栈跟踪来查看实际的 UI。这不会出现在生产中。我相信反应开发代码会查看抛出异常的位置,如果它在您的代码中,那么您会看到用户界面。

请参阅:使用 ErrorBoundary 捕获后 React 仍然显示错误