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!