在与 react-router 的反应中管理加载栏的状态
Managing state for a loading bar in react with react-router
我在 React 中有一个应用程序,它使用 material-ui 的响应式抽屉组件。我们称它为 ResponsiveDrawer。在这个组件中,我有一个名为 "loading".
的状态变量
class ResponsiveDrawer extends React.Component {
constructor(props) {
super(props);
this.state = {
loading:false
}
this.setLoading = this.setLoading.bind(this);
}
setLoading(loading) {
this.setState({loading:loading});
}
...
我想根据 loading
状态变量在页面顶部显示一个 LinearProgress 组件。
...
render() {
return (
<div className={classes.root}>
{this.state.loading ? <LinearProgress/> : ""}
...
在 ResponsiveDrawer 内部,我也在使用 React 路由器来渲染一些子组件。
...
<main className={classes.content}>
<div className={classes.contentWrapper}>
<Switch>
<Route
exact
path="/investments"
component={InvestmentsComponent}
/>
...
</Switch>
</div>
</main>
</div>
在 Investments 组件中,我正在从 API 中获取数据。
我想做的是将 ResponsiveDrawer 组件中的加载状态设置为 true
,然后在成功获取后将其设置回 false
。
所以我将 ResponsiveDrawer 的 setLoading 函数作为 props 传递给了 InvestmentsComponent:
InvestmentsComponent = <Investments setLoading={this.setLoading} />
然后尝试在 componentDidMount()
上将其设置为 true
componentDidMount() {
this.props.setLoading(true);
fetchInvestments(); // sets loading to false upon completion
}
fetchInvestments() {
fetch("/api/investments", {
credentials: "same-origin",
headers: {
"Cache-Control": "no-cache"
}
})
.then(res => {
if (!res.ok) throw Error(res.status);
return res.json();
})
.then(responseJson => {
this.props.setLoading(false);
this.setState({ investments: responseJson });
})
.catch(err => {
console.error("Unable to fetch investments"); // show error message
});
}
然而,当我这样做时,反应进入无限循环 - 我假设当 loading
的状态发生变化时,它还会重新加载投资组件路由,然后再次设置加载状态。
我最终得到:
Maximum update depth exceeded. This can happen when a component
repeatedly calls setState inside componentWillUpdate or
componentDidUpdate. React limits the number of nested updates to
prevent infinite loops.
这个难题的潜在解决方案是什么?
我实际上通过使用 render
而不是 component
prop
以不同的方式渲染路由组件解决了这个问题
<Route exact path="/investments" render={InvestmentsComponent} />
我在 React 中有一个应用程序,它使用 material-ui 的响应式抽屉组件。我们称它为 ResponsiveDrawer。在这个组件中,我有一个名为 "loading".
的状态变量class ResponsiveDrawer extends React.Component {
constructor(props) {
super(props);
this.state = {
loading:false
}
this.setLoading = this.setLoading.bind(this);
}
setLoading(loading) {
this.setState({loading:loading});
}
...
我想根据 loading
状态变量在页面顶部显示一个 LinearProgress 组件。
...
render() {
return (
<div className={classes.root}>
{this.state.loading ? <LinearProgress/> : ""}
...
在 ResponsiveDrawer 内部,我也在使用 React 路由器来渲染一些子组件。
...
<main className={classes.content}>
<div className={classes.contentWrapper}>
<Switch>
<Route
exact
path="/investments"
component={InvestmentsComponent}
/>
...
</Switch>
</div>
</main>
</div>
在 Investments 组件中,我正在从 API 中获取数据。
我想做的是将 ResponsiveDrawer 组件中的加载状态设置为 true
,然后在成功获取后将其设置回 false
。
所以我将 ResponsiveDrawer 的 setLoading 函数作为 props 传递给了 InvestmentsComponent:
InvestmentsComponent = <Investments setLoading={this.setLoading} />
然后尝试在 componentDidMount()
componentDidMount() {
this.props.setLoading(true);
fetchInvestments(); // sets loading to false upon completion
}
fetchInvestments() {
fetch("/api/investments", {
credentials: "same-origin",
headers: {
"Cache-Control": "no-cache"
}
})
.then(res => {
if (!res.ok) throw Error(res.status);
return res.json();
})
.then(responseJson => {
this.props.setLoading(false);
this.setState({ investments: responseJson });
})
.catch(err => {
console.error("Unable to fetch investments"); // show error message
});
}
然而,当我这样做时,反应进入无限循环 - 我假设当 loading
的状态发生变化时,它还会重新加载投资组件路由,然后再次设置加载状态。
我最终得到:
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
这个难题的潜在解决方案是什么?
我实际上通过使用 render
而不是 component
prop
<Route exact path="/investments" render={InvestmentsComponent} />