React-Router:如何在路由转换之前等待异步动作

是否可以thunk在特定路由上调用称为a的异步redux操作,并且在响应成功或失败之前不执行转换?

我们需要从服务器加载数据并用初始值填写表单。从服务器获取数据之前,这些初始值不存在。

像这样的一些语法会很棒:

<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')

});

}

}

来自关于异步操作的redux文档http://redux.js.org/docs/advanced/AsyncActions.html

  • 通知减速器该请求开始的动作。

减速器可以通过在状态下切换isFetching标志来处理此操作。这样,UI知道了显示微调框的时候了。

  • 通知减速器该请求成功完成的操作。

减速器可以通过将新数据合并到它们管理的状态并重置isFetching来处理此操作。UI将隐藏微调框,并显示获取的数据。

  • 通知减速器该请求失败的操作。

减速器可以通过重置isFetching来处理此操作。另外,某些化简工具可能希望存储错误消息,以便UI可以显示它。

我按照您的情况作为粗略指导,遵循了以下一般模式。您不必使用诺言

// 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({}, state, {

fetching: false,

formData: action.payload

})

case FETCH_FORM_DATA_ERROR:

return Object.assign({}, state, {

fetching: false,

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)

以上是 React-Router:如何在路由转换之前等待异步动作 的全部内容, 来源链接: utcz.com/qa/410332.html

回到顶部