React Redux Thunk在一次调用时触发多个操作

时间:2018-03-17 10:01:57

标签: reactjs redux redux-thunk

我有一个动作反过来必须影响我的app状态的许多其他区域。在这种情况下,当用户从下拉列表中选择网站时,它必须更新许多其他组件。我现在正在这样做:

setSelectedWebsite (websiteId) {
    // The core reason for this component
    this.props.setSelectedWebsite(websiteId);

    // Fetch all associated accounts
    this.props.fetchAllAccounts(websiteId)

    // Several other "side effect" calls here...
}

为了使一个组件成为一个目的,这感觉就像一个坏习惯。

在组件的一次通话中触发多项操作的最佳做​​法是什么?

2 个答案:

答案 0 :(得分:1)

您可以使用redux-thunk

您的组件方法:

setSelectedWebsite(websiteId){
    this.props.handleSetSelectedWebsite(websiteId) // this is a thunk
}

包含动作创建者/ thunks的Redux文件:

// this function is a thunk

export const handleSetSelectedWebsite = (websiteId) => (dispatch) => {
    dispatch(setSelectedWebsite(websiteId))
    dispatch(fetchAllAccounts(websiteId))
}

// these function are action creators (or could be other thunks if you style them the same way as the thunk above)

const setSelectedWebsite = (websiteId) => {
    // your code
}

const fetchAllAccounts = (websiteId) => {
    // your code
}

答案 1 :(得分:0)

为了处理redux应用程序中的复杂副作用,我建议使用Redux Sagas。我已经看到它的使用在大大小小的项目中越来越受欢迎,并且有充分的理由。

使用sagas,在您提供的示例中,您可以通过mapDispatchToProps提供的函数发出单个动作,并让传奇照顾其余部分。例如:(以下示例假设通量标准操作)

//import redux connect, react, etc

class SiteSelector extends React.Component {

    render() {
        const id = this.props.id;

        return (
           <button onClick={ () => this.props.action(id)>Click Me</button>
        )
    }
}

const mapStateToProps = (state) => ({
    id: state.websiteId
})

const mapDispatchToProps = dispatch => ({
    action: (id) => dispatch(setSelectedWebsite(id))
})

export connect(mapStateToProps, mapDispatchToProps)(SiteSelector)

现在你可以处理像setSelectedWebsite这样的传奇中发出的动作:

//import all saga dependencies, etc 

export function* selectSite(action) {
  const id = action.payload.id
  yield put(Actions.selectWebsite(id))
  const results = yield call(Api.fetchAllAccounts, id)
  yield //do something complex with results
  yield //do something else...
  yield //and keep going...
}

// Our watcher Saga: spawn a new selectSite task every time the action from setSelectedWebsite is dispatched 
export function* watchForSiteSelection() {
  yield takeEvery('SITE_SELECTED_ACTION', selectSite)
}

参考结帐文档:Redux Sagas