首页 > 解决方案 > React 中的错误边界:为什么 'throw new Error('some message')' 失败而 'throw errorObj' 工作?

问题描述

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

假设我有一个简单的组件,它使用 React 钩子从远程 API 加载一些数据。由于错误边界本身无法使用异步进程catch,因此该组件不会在 中引发错误,而是将其存储errorstate在下一次重新渲染时引发

// 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

}

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

// 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;

我的错误边界很简单:

//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
  }
}

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

// index.js
ReactDOM.render(<Catch><App/></Catch>, document.getElementById('root'));

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

 if (error) throw error

 if (error) throw new Error('some message')

或者

 if (error) throw new Error(error.message)

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

标签: javascriptreactjserror-handlingreact-hooks

解决方案


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

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


推荐阅读