我正在使用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获取数据的动作创建者。
答案 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
会在数据提取过程中呈现,并且可以使用道具loading
和progress
来显示微调器或其他内容
答案 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)