javascript - React 中的错误边界:为什么 'throw new Error('some message')' 失败而 'throw errorObj' 工作?
问题描述
我正在学习 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)
错误边界不起作用,应用程序崩溃。为什么是这样?我这样问是为了更好地理解我在做什么,而不仅仅是让它发挥作用。谢谢你的帮助!
解决方案
这是开发环境的产物。您可以通过点击“escape”或“X”来关闭堆栈跟踪来查看您的实际 UI。这不会出现在生产中。我相信反应开发代码会查看抛出异常的位置,如果它在您的代码中,那么您会看到 UI。
推荐阅读
- reactjs - 与 React 一起使用时 Apollo 重新获取
- c# - 映射空值导致默认类型值(Automapper ADO.NET)
- ruby-on-rails - Rails 范围内的正则表达式未捕获正确的值
- spring-security - Keycloak - 将客户端登录限制为组成员
- node.js - 通过 webhook 将 basecamp 3 与 Mavenlink 集成?
- reactjs - Keycloak - 保护 Spring Boot 应用程序
- c - 如何通过喜欢的列表编写出队的功能出队
- html - 如何防止延迟样式加载每个页面加载而不是第一次加载?
- google-app-maker - AppMaker - 仅在选项卡中显示过滤的项目
- javascript - 尝试访问 JSON 数组中的密钥