React 中的错误边界:为什么“throw new Error('some message')”失败而 'throw errorObj' 有效?
Error Boundary in React: why does 'throw new Error('some message')' fail and 'throw errorObj' work?
我正在学习 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.
参见:
我正在学习 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.
参见: