我正在学习React中的错误边界。我认为我对基础知识有很好的了解,但是在为异步过程(例如加载数据)实现它们时遇到了麻烦。
假设我有一个简单的组件,该组件使用React挂钩从远程API加载一些数据。由于错误边界本身无法使用异步处理来解决,因此不会在catch
中引发错误,因此该组件将error
存储在state
中,并在下次重新渲染时引发>
// 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)
错误边界不起作用,应用程序崩溃。为什么是这样?我要问的是,我可以更好地了解自己在做什么,而不仅仅是使它起作用。感谢您的帮助!
答案 0 :(得分:1)
这是开发环境的产物。 您可以通过单击“转义”或“ X”以消除堆栈跟踪来查看实际的UI。这不会出现在生产中。 我相信react开发人员代码会查看引发异常的位置,如果异常在您的代码中,那么您会看到UI。
请参阅:React still showing errors after catching with ErrorBoundary