首页 > 解决方案 > 仅在从反应路由器中的第 3 方收到数据后才更改组件

问题描述

Youtube、Instagram、Github 是如何在收到数据后才改变内容的?

<Switch>
    ...Other Route
    <Route path = "/" exact component={HomeComp} />
    <Route path = "/articles" component={ArticleComp} />
</Switch>

据我所知,当我单击 aNav Link将 url from替换//articles组件时,也会将其替换为HomeCompto ArticleComp。但是我从其他 SPA 应用程序(我上面提到的那些)中看到的,即使 url 被替换但组件没有被替换,而是有一个进度条,组件只被替换,直到收到来自 fetch 请求的响应。如果您听不懂我的话,我会尝试添加图片以便更好地理解

  1. 如果我想做类似的事情,我应该在哪里执行获取请求?从文档它说它应该在componentsDidMount(). 但这似乎不对,因为在加载数据之前组件不是初始的。
  2. 很简单的问题如何才能达到目标?仅在收到 fetch 响应而不是 replace url > replace components > start fetch request. 我寻求的解决方案就像 github、youtube 的做法(下图)。
  3. 如果我想实现这一点,我还能坚持使用 react-router 吗?

在此处输入图像描述

很抱歉一直重复同样的问题,我担心我问的不清楚。英语不是我的主要语言,所以我很难研究,我不知道包含什么关键字来找到正确的解决方案。如果之前有人问过这个问题,请为我提供链接。谢谢!

标签: reactjsreact-routerreact-redux

解决方案


因此,这里的假设是您希望 UI 的某些部分在不同页面中通用。即..HomeCompArticleComp.

想象一下,你有一个 Layout 组件(容器):

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Header from './Header';
import Footer from './Footer';

class Layout extends Component {
    static propTypes = {
        actions: PropTypes.object.isRequired,
        children: PropTypes.node,
    };

    render() {
        return (
            <div className={_className}>
               <Header />
               <div className={_rhsContentClassName}>
                 { this.props.children }
               </div>
               <Footer />
            </div>
        );
    }
}
export default Layout;

现在,在您的路线文件中,您将路线描述为,

<Switch>
    ...Other Route
    <Route path = "/" exact component={HomeComp} />
    <Route path = "/articles" component={ArticleComp} />
</Switch>

对于每个 Route 组件,HomeComp或者ArticleComp,您的反应组件应如下所示:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Layout from './Layout';
import Preloader from './Preloader';

class ArticleComp extends Component {
    static propTypes = {
        actions: PropTypes.object.isRequired,
    };

    componentWillMount() {
         this.setState({ isLoading: true };
         actions
            .fetchData()
            .then(() => {
               // do something
               // store data for the content
               this.setState({ isLoading: false };
            });
    }

    render() {
        if (isLoading) 
          return <Preloader />;

        return (
            <Layout>
               <div> {/* content based on the fetch request */}</div>
            </Layout>
        );
    }
}
export default ArticleComp;

这样,您就可以将您的 Header、Footer 或其他静态(甚至是动态关注点)与真正的基于请求的内容隔离开来。


推荐阅读