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

React Redux Thunk trigger multiple actions on one call

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

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...
}

为了让一个组件服务于一个目的,这感觉像是一种不好的做法。

在一个组件的一次调用中触发多个操作的最佳实践是什么?

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

使用 sagas,在您提供的示例中,您可以从通过 mapDispatchToProps 提供的函数发出单个操作,然后让 saga 处理其余部分。例如:(以下示例假定通量标准动作)

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

现在您可以像这样在 saga 中处理从 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

你可以使用 redux-thunk.

您的组件的方法:

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

你的带有 action creators/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
}