reactjs – React-Router:如何在路由转换之前等待异步操作
是否可以在特定路由上调用异步redux操作(称为thunk),并且在响应成功或失败之前不执行转换?
用例 我们需要从服务器加载数据并使用初始值填充表单.在从服务器获取数据之前,这些初始值不存在. 像这样的一些语法会很棒: <Route path="/myForm" component={App} async={dispatch(loadInitialFormValues(formId))}>
回答在响应成功或失败之前阻止转换到新路由的原始问题:
因为你正在使用redux thunk,你可以在动作创建器中成功或失败触发重定向.我不知道你的具体动作/动作创建者是什么样的,但这样的事情可能有效: import { browserHistory } from 'react-router' export function loadInitialFormValues(formId) { return function(dispatch) { // hit the API with some function and return a promise: loadInitialValuesReturnPromise(formId) .then(response => { // If request is good update state with fetched data dispatch({ type: UPDATE_FORM_STATE,payload: response }); // - redirect to the your form browserHistory.push('/myForm'); }) .catch(() => { // If request is bad... // do whatever you want here,or redirect browserHistory.push('/myForm') }); } } 跟进.在输入路径/组件的componentWillMount并显示微调器时加载数据的常见模式: 来自异步操作http://redux.js.org/docs/advanced/AsyncActions.html的redux文档
我使用您的情况作为粗略的指导方针,遵循下面的这种一般模式.您不必使用承诺 // action creator: export function fetchFormData(formId) { return dispatch => { // an action to signal the beginning of your request // this is what eventually triggers the displaying of the spinner dispatch({ type: FETCH_FORM_DATA_REQUEST }) // (axios is just a promise based HTTP library) axios.get(`/formdata/${formId}`) .then(formData => { // on successful fetch,update your state with the new form data // you can also turn these into their own action creators and dispatch the invoked function instead dispatch({ type: actions.FETCH_FORM_DATA_SUCCESS,payload: formData }) }) .catch(error => { // on error,do whatever is best for your use case dispatch({ type: actions.FETCH_FORM_DATA_ERROR,payload: error }) }) } } // reducer const INITIAL_STATE = { formData: {},error: {},fetching: false } export default function(state = INITIAL_STATE,action) { switch(action.type) { case FETCH_FORM_DATA_REQUEST: // when dispatch the 'request' action,toggle fetching to true return Object.assign({},state,{ fetching: true }) case FETCH_FORM_DATA_SUCCESS: return Object.assign({},{ fetching: false,formData: action.payload }) case FETCH_FORM_DATA_ERROR: return Object.assign({},error: action.payload }) } } // route can look something like this to access the formId in the URL if you want // I use this URL param in the component below but you can access this ID anyway you want: <Route path="/myForm/:formId" component={SomeForm} /> // form component class SomeForm extends Component { componentWillMount() { // get formId from route params const formId = this.props.params.formId this.props.fetchFormData(formId) } // in render just check if the fetching process is happening to know when to display the spinner // this could also be abstracted out into another method and run like so: {this.showFormOrSpinner.call(this)} render() { return ( <div className="some-form"> {this.props.fetching ? <img src="./assets/spinner.gif" alt="loading spinner" /> : <FormComponent formData={this.props.formData} /> } </div> ) } } function mapStateToProps(state) { return { fetching: state.form.fetching,formData: state.form.formData,error: state.form.error } } export default connect(mapStateToProps,{ fetchFormData })(SomeForm) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |