在前往路线之前显示进度条

时间:2017-07-18 06:16:57

标签: javascript reactjs redux react-router react-router-redux

我正在使用redux开发通用反应应用程序。我使用react-router v3。 我想显示进度条“BEFORE”进入下一条路线(下一条路线是从API获取数据)。

例如,想象一下我在“主页”,我想去“提交页面”。当我点击提交链接(react-router链接)时,首先在“主页”中显示进度条 并等待提交页面数据然后< / strong>转到“提交页面”。 我的反应路线:

<Route component={App}>
        <Route path={HomingRoutes.HomePage} component={HomePage}/>
        <Route path={HomingRoutes.SubmitPage} component={SubmitPage}/>
        <Route path={HomingRoutes.SearchPage} component={SearchPage}/>
        <Route path={`${HomingRoutes.DealsPage}`} component={DealsPage}/>
        <Route path={`${HomingRoutes.DealPage}/:id(/:title)`} component={DealPage}/>
        <Route path={`${HomingRoutes.Detail}/:id(/:title)`} component={DetailPage}/>
        <Route path="*" component={NoMatch}/>
    </Route>

在主页:

<Link to "/Submit" >Submit</Link>

我的提交页面容器代码是:

class SubmitContainer extends React.Component {
    static readyOnActions(dispatch) {
        return Promise.all([
            dispatch(SubmitActions.fetchSubmitInitialData()),
        ]);
    }
    componentDidMount() {
        this.props.fetchSubmitInitialData();
    }
}

fetchSubmitInitialData ”是一个从API获取数据的动作创建者。

2 个答案:

答案 0 :(得分:2)

一种解决方案是将placeholder组件作为道具传递给SubmitPage,只有在获取数据时才会呈现。

所以你可以使用类似的东西:

class SubmitContainer extends React.Component {
  state = {
    loading: true
    progress: 0,

  }

  componentDidMount() {
    // fetch some data and update the state
    // consider updating the progress more often
    this.props.fetchSubmitInitialData()
      .then(() => {
         this.setState({ loading: false, progress: 100 })
      })
  }

  render() {
    const Placeholder = this.props.placeholder
    // Show the placeholder when loading
    if (this.state.loading) {
      return <Placeholder loading progress={this.state.progress} />
    }

    // Otherwise render your component with the data
    return <SubmitPage data={/*..*/}>
  }
}

最后通过你可以使用组件HomePage作为占位符,如下所示:

<Route path={HomingRoutes.HomePage} component={HomePage}/>
<Route path={HomingRoutes.SubmitPage} render={(props) => (
         <SubmitContainer {...props} placeholder={HomePage} />
   )}/>

这里我使用React路由器v4的渲染道具。但我确定版本3的等价物

现在HomePage会在数据提取过程中呈现,并且可以使用道具loadingprogress来显示微调器或其他内容

答案 1 :(得分:0)

您可以在路由器中添加onEnter挂钩并在onEnter.js文件夹中添加SubmitContainer,然后将fetchSubmitInitialData移至onEnter.js,然后在此处导入您的商店,派遣它。实现可能如下所示:

你的反应路线

import { onEnterSubmitPage } from './your onEnter path/onEnter'

<Route component={App}>
    <Route path={HomingRoutes.HomePage} component={HomePage}/>
    <Route path={HomingRoutes.SubmitPage} component={SubmitPage} onEnter={onEnterSubmitPage}/>
    <Route path={HomingRoutes.SearchPage} component={SearchPage}/>
    <Route path={`${HomingRoutes.DealsPage}`} component={DealsPage}/>
    <Route path={`${HomingRoutes.DealPage}/:id(/:title)`} component={DealPage}/>
    <Route path={`${HomingRoutes.Detail}/:id(/:title)`} component={DetailPage}/>
    <Route path="*" component={NoMatch}/>
</Route>

在SubmitPage容器中创建onEnter.js文件:

/**
 *  Import dependencies and action creators
 */
import { store } from '../../index'
import { fetchSubmitInitialData } from './actions'

/**
 *  Define onEnter function
 */
 export function onEnterSubmitPage() {

   store.dispatch(fetchSubmitInitialData())
 }

然后我们也可以将进度条状态集成到redux中。

actions.js

/** Import all dependencies here **/
import axios from 'axios'
import { FETCH_SUBMIT_INITIAL_DATA, IS_FETCHING_INITIAL_DATA } from './constants'

export function fetchSubmitInitialData() {
 /** this dispatch is from middleware **/ 
 return (dispatch) => {
     /** this will set progress bar to true **/
     dispatch(fetchSubmitInitialData(true))

     /** Your fetching action here, this will depend on your configuration **/
      axios.get(`url`, {{ headers: `bearer //your token`}})
         .then( (response) => {
            dispatch(fetchSubmitInitialData(false))
      })  
  }
 }

export function isFetchInitialData(status) {
 return {
  type: IS_FETCHING_INITIAL_DATA,
  status
 }
}

因此无需获取SubmitPage容器内的数据。

一种解决方案是将占位符组件作为道具传递给您的SubmitPage,只有在获取数据时才会呈现。

所以你可以使用类似的东西:

class SubmitContainer extends React.Component {

  render() {
   /** this come from your reducer **/
   const { isFetching, submitInitialData } = this.props
   // Show the placeholder when loading
   if (isFetching) {
     return <Loader />
   }

  // Otherwise render your component
  return <SubmitPage data={/*..*/}>
 }
}

// Map state to props
const mapStatetoProps = ({ app }) => {
     isFetching: //,
     submitInitialData: //
}

export default connect(mapStatetoProps, null)(SubmitContainer)