Reactjs 反应路由器:如何在路由转换之前等待异步操作
是否可以在特定路由上调用称为Reactjs 反应路由器:如何在路由转换之前等待异步操作,reactjs,state,redux,react-router,react-router-redux,Reactjs,State,Redux,React Router,React Router Redux,是否可以在特定路由上调用称为thunk的异步redux操作,并且在响应成功或失败之前不执行转换 用例 我们需要从服务器加载数据并用初始值填充表单。在从服务器获取数据之前,这些初始值不存在 像这样的一些语法会很好: <Route path="/myForm" component={App} async={dispatch(loadInitialFormValues(formId))}> 回答在响应成功或失败之前阻止转换到新路由的原始问题: 因为您使用的是redux thunk,所以您
thunk
的异步redux操作,并且在响应成功或失败之前不执行转换
用例
我们需要从服务器加载数据并用初始值填充表单。在从服务器获取数据之前,这些初始值不存在
像这样的一些语法会很好:
<Route path="/myForm" component={App} async={dispatch(loadInitialFormValues(formId))}>
回答在响应成功或失败之前阻止转换到新路由的原始问题: 因为您使用的是redux thunk,所以您可以在action creator中成功或失败触发重定向。我不知道您的特定动作/动作创建者是什么样子的,但类似的东西可能会起作用:
从'react router'导入{browserHistory}
导出函数loadInitialFormValues(formId){
返回功能(调度){
//使用某个函数点击API并返回承诺:
加载初始值返回承诺(formId)
。然后(响应=>{
//如果请求是良好的,则使用获取的数据更新状态
分派({type:UPDATE\u FORM\u STATE,payload:response});
//-重定向到您的表单
browserHistory.push('/myForm');
})
.catch(()=>{
//如果请求不正确。。。
//在这里做你想做的,或者重定向
browserHistory.push(“/myForm”)
});
}
}
跟进。输入路由/在组件上加载数据的常见模式将装载组件并显示微调器:
从异步操作的redux文档
- 通知还原程序请求已开始的操作
- 通知还原程序请求已成功完成的操作
- 通知还原程序请求失败的操作
//操作创建者:
导出函数fetchFormData(formId){
返回调度=>{
//发出请求开始信号的操作
//这就是最终触发微调器显示的原因
分派({type:FETCH\u FORM\u DATA\u REQUEST})
//(axios只是一个基于承诺的HTTP库)
get(`/formdata/${formId}`)
。然后(formData=>{
//成功获取后,使用新表单数据更新您的状态
//您还可以将它们转换为自己的动作创建者,并分派调用的函数
分派({type:actions.FETCH\u FORM\u DATA\u SUCCESS,payload:formData})
})
.catch(错误=>{
//在出现错误时,做对您的用例最好的事情
分派({type:actions.FETCH\u FORM\u DATA\u ERROR,payload:ERROR})
})
}
}
//减速器
常量初始状态={
formData:{},
错误:{},
抓取:假
}
导出默认函数(状态=初始状态,动作){
开关(动作类型){
案例获取表格数据请求:
//分派“请求”操作时,将获取切换为true
返回Object.assign({},state,{fetching:true})
案例获取\表单\数据\成功:
返回Object.assign({},state{
取景:假,
formData:action.payload
})
案例获取\表单\数据\错误:
返回Object.assign({},state{
取景:假,
错误:action.payload
})
}
}
//如果需要的话,访问URL中的formId的路由可以是这样的
//我在下面的组件中使用此URL参数,但您可以根据需要访问此ID:
//表单组件
类以某种形式扩展组件{
组件willmount(){
//从路由参数获取formId
常量formId=this.props.params.formId
this.props.fetchFormData(formId)
}
//在渲染中,只需检查抓取过程是否正在进行,以了解何时显示微调器
//这也可以抽象为另一个方法,并像这样运行:{this.showFormOrSpinner.call(this)}
render(){
返回(
{this.props.fetching?
:
}
)
}
}
函数MapStateTops(状态){
返回{
获取:state.form.fetching,
formData:state.form.formData,
错误:state.form.error
}
}
导出默认连接(MapStateTops,{fetchFormData})(某种形式)
首先,我想说的是,使用react router的OneNet获取数据的主题挂钩是否是一种好的做法,然而这就是这样的做法:
您可以将redux存储传递给您的路由器
。将以下组件作为根组件,其中安装了Router
:
...
import routes from 'routes-location';
class Root extends React.Component {
render() {
const { store, history } = this.props;
return (
<Provider store={store}>
<Router history={history}>
{ routes(store) }
</Router>
</Provider>
);
}
}
...
。。。
从“路线位置”导入路线;
类根扩展了React.Component{
render(){
const{store,history}=this.props;
返回(
{路线(商店)}
);
}
}
...
您的路线将类似于:
import ...
...
const fetchData = (store) => {
return (nextState, transition, callback) => {
const { dispatch, getState } = store;
const { loaded } = getState().myCoolReduxStore;
// loaded is a key from my store that I put true when data has loaded
if (!loaded) {
// no data, dispatch action to get it
dispatch(getDataAction())
.then((data) => {
callback();
})
.catch((error) => {
// maybe it failed because of 403 forbitten, we can use tranition to redirect.
// what's in state will come as props to the component `/forbitten` will mount.
transition({
pathname: '/forbitten',
state: { error: error }
});
callback();
});
} else {
// we already have the data loaded, let router continue its transition to the route
callback();
}
}
};
export default (store) => {
return (
<Route path="/" component={App}>
<Route path="myPage" name="My Page" component={MyPage} onEnter={fetchData(store)} />
<Route path="forbitten" name="403" component={PageForbitten} />
<Route path="*" name="404" component={PageNotFound} />
</Route>
);
};
导入。。。
...
常量fetchData=(存储)=>{
返回(下一个状态、转换、回调)=>{
const{dispatch,getState}=store;
const{loaded}=getState().mycolreduxstore;
//loaded是存储区中的一个密钥,当数据加载后,我将其置为true
如果(!已加载){
//没有数据,请发送操作以获取数据
调度(getDataAction())
.然后((数据)=