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