Und*_*per 17 browser-history reactjs react-router
当我们的React 16代码库中出现错误时,它会被我们的顶级错误边界捕获.ErrorBoundary发生这种情况时,组件会愉快地呈现错误页面.
ErrorBoundary所在的位置
return (
<Provider store={configureStore()}>
<ErrorBoundary>
<Router history={browserHistory}>{routes}</Router>
</ErrorBoundary>
</Provider>
)
Run Code Online (Sandbox Code Playgroud)
但是,使用浏览器后退按钮(单击一次)导航回来时,URL会在地址中更改,但页面不会更新.
我已经尝试将错误边界向下移动到组件树,但此问题仍然存在.
关于这个问题在哪里的任何线索?
jda*_*ies 31
op现在可能已经找到了一个解决方案,但是为了其他任何有这个问题的人的利益,我将解释为什么我认为它正在发生以及可以做些什么来解决它.
这可能是由于ErrorBoundary中的条件呈现呈现错误消息,即使历史记录已更改.
虽然上面没有显示,但ErrorBoundary中的render方法可能类似于:
render() {
if (this.state.hasError) {
return <h1>An error has occurred.</h1>
}
return this.props.children;
}
Run Code Online (Sandbox Code Playgroud)
其中hasError在componentDidCatch生命周期方法中设置.
一旦设置了ErrorBoundary中的状态,它将始终呈现错误消息,直到状态发生变化(上例中的hasError为false).即使历史记录发生更改,也不会呈现子组件(在这种情况下为路由器组件).
要解决此问题,请通过包装ErrorBoundary的导出来使用react-router withRouter更高阶组件,以通过props访问历史记录:
export default withRouter(ErrorBoundary);
Run Code Online (Sandbox Code Playgroud)
在ErrorBoundary构造函数中,从props中检索历史记录并设置处理程序以使用history.listen监听对当前位置的更改.当位置发生变化(单击后退按钮等)时,如果组件处于错误状态,则会清除该位置,以便再次渲染子项.
const { history } = this.props;
history.listen((location, action) => {
if (this.state.hasError) {
this.setState({
hasError: false,
});
}
});
Run Code Online (Sandbox Code Playgroud)
小智 8
要添加到上面 jdavies 的回答中,请确保在 a componentDidMountor 中注册历史监听器useEffect([]用于表示它没有依赖项),并在 a or return 语句中取消注册,否则您可能会遇到在未安装的组件中调用的问题.componentWillUnmountuseEffectsetState
例子:
componentDidMount() {
this.unlisten = this.props.history.listen((location, action) => {
if (this.state.hasError) {
this.setState({ hasError: false });
}
});
}
componentWillUnmount() {
this.unlisten();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1895 次 |
| 最近记录: |