Error Boundary in React: why does 'throw new Error('some message')' fail and 'throw errorObj' work?

倾然丶 夕夏残阳落幕 提交于 2020-12-29 04:22:08

问题


I'm learning Error Boundaries in React. I think I've got a good basic understanding but am having trouble implementing them for asynchronous processes, such as loading data.

Let's say I have a simple component that, using React hooks, loads some data from a remote API. Since error boundaries won't work using asynchronous processes per se, instead of throwing an error in catch, this component stores the error in state and throws it on next re-render

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

}

This component is used in my App:

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

My Error Boundary is very simple:

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

This Catch component then wraps the App:

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

The Error Boundary seems to work when I throw an error inside MovieDb, such as when calling the API. However, when I change

 if (error) throw error

to

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

or

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

the Error Boundary doesn't work and the app crashes. Why is this? I'm asking so that I can understand better what I'm doing, not just to make it work. Thanks for any help!


回答1:


This is an artifact of the dev environment. You can see your actual UI by hitting "escape" or the "X" to dismiss the stack trace. This won't show up in production. I believe the react dev code looks at where the Exception was thrown and if it's in your code then you see the UI.

See: React still showing errors after catching with ErrorBoundary



来源:https://stackoverflow.com/questions/57274551/error-boundary-in-react-why-does-throw-new-errorsome-message-fail-and-th

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!