Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 反应路由器:如何在路由转换之前等待异步操作_Reactjs_State_Redux_React Router_React Router Redux - Fatal编程技术网

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文档

  • 通知还原程序请求已开始的操作
还原程序可以通过在中切换isFetching标志来处理此操作 国家。这样,UI就知道是时候显示微调器了

  • 通知还原程序请求已成功完成的操作
还原程序可以通过将新数据合并到 说明他们管理和重置isFetching。用户界面将隐藏 微调器,并显示获取的数据

  • 通知还原程序请求失败的操作
还原程序可以通过重置isFetching来处理此操作。 此外,某些还原程序可能希望存储错误消息,以便 用户界面可以显示它

我遵循了下面的一般模式,将您的情况作为粗略的指南。你不必使用承诺

//操作创建者:
导出函数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())
.然后((数据)=