简体   繁体   English

与React-Router一起管理加载条的状态

[英]Managing state for a loading bar in react with react-router

I have an app in React which uses material-ui's responsive drawer component. 我在React中有一个应用程序,它使用了Material-ui的响应式抽屉组件。 Let's call it ResponsiveDrawer. 我们称它为ResponsiveDrawer。 In this component I have a state variable called "loading". 在此组件中,我有一个状态变量称为“ 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});
    }
    ...

I want to display a LinearProgress component at the top of the page, depending on the loading state variable. 我想在页面顶部显示LinearProgress组件,具体取决于loading状态变量。

    ...
    render() {
        return (
            <div className={classes.root}>
                {this.state.loading ? <LinearProgress/> : ""} 
                ...

Inside ResponsiveDrawer I am also using react router to render some child components. 在ResponsiveDrawer内部,我还使用React Router渲染一些子组件。

                ...
                <main className={classes.content}>
                    <div className={classes.contentWrapper}>
                        <Switch>
                            <Route
                                exact
                                path="/investments"
                                component={InvestmentsComponent}
                            />
                            ...
                        </Switch>
                     </div>
               </main>
          </div>

Inside Investments component, I am doing a fetch from an API. 在投资组件内部,我正在从API中提取数据。 What I would like to do, is to set the loading state in the ResponsiveDrawer component to true and then set it back to false upon successful fetch. 我想做的是将ResponsiveDrawer组件中的加载状态设置为true ,然后在成功获取后将其设置为false

So I passed the setLoading function of the ResponsiveDrawer into InvestmentsComponent as props: 因此,我将ResponsiveDrawer的setLoading函数作为props传递给InvestmentsComponent:

 InvestmentsComponent = <Investments setLoading={this.setLoading} />

And then tried to set it to true on componentDidMount() 然后尝试在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
            });
    }

However, when I do this, react goes into infinite loop - I assume that when the state of loading changes, it also reloads the investments component route which then sets the loading state again. 但是,当我这样做时,反应会陷入无限循环-我假设当loading状态发生变化时,它还会重新加载投资组件路线,然后再次设置加载状态。

I end up with: 我最终得到:

Maximum update depth exceeded. 超过最大更新深度。 This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. 当组件重复调用componentWillUpdate或componentDidUpdate内部的setState时,可能会发生这种情况。 React limits the number of nested updates to prevent infinite loops. React限制了嵌套更新的数量,以防止无限循环。

What could be a potential solution to this conundrum? 有什么可能解决这个难题?

我实际上是通过使用另一种方式渲染路线组件来解决此问题的,方法是使用render而不是component prop

 <Route exact path="/investments" render={InvestmentsComponent} />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM