这是 redux 中间件反模式吗?如何使用中间件正确构建异步操作
Is this a redux middleware anti-pattern? How to properly build async actions with middleware
刚刚构建了我的第一个 API 中间件,只是想知道我应该在哪里为调度多个动作的动作创建者链接承诺。我做的是不是反模式:
export const fetchChuck = () => {
return {
[CALL_API]: {
types: [ CHUCK_REQUEST, CHUCK_SUCCESS, CHUCK_FAILURE ],
endpoint: `jokes/random`
}
}
}
export const saveJoke = (joke) => {
return { type: SAVE_JOKE, joke: joke }
}
export const fetchAndSaveJoke = () => {
return dispatch => {
dispatch(fetchChuck()).then((response) => {
dispatch(saveJoke(response.response.value.joke))
})
}
}
fetchAndSaveJoke 应该在我的 React 组件中分派 section 动作,还是可以将它作为自己的动作创建者?
我想说,在 Redux 世界的这一点上,还不是很清楚什么是最佳实践以及 anti-patterns 是什么。这是一个非常不拘一格的工具。虽然这对于多样化生态系统的蓬勃发展非常有利,但它确实给寻求组织应用程序的方法而不 运行 陷入陷阱或过多样板文件的人们带来了挑战。据我所知,您的方法似乎与 Redux 指南中的建议大致一致。对我来说有趣的一件事是 CHUCK_SUCCESS
似乎应该使 SAVE_JOKE
变得不必要。
我个人觉得让 action creator 派发更多的 action 很尴尬,所以我想出了 react-redux-controller 背后的方法。它是全新的,所以肯定不是 "best practice",但我会把它放在那里以防您或其他人想尝试一下。在该工作流程中,您将拥有一个类似于以下内容的控制器方法:
// actions/index.js
export const CHUCK_REQUEST = 'CHUCK_REQUEST';
export const CHUCK_SUCCESS = 'CHUCK_SUCCESS';
export const CHUCK_FAILURE = 'CHUCK_FAILURE';
export const chuckRequest = () => { type: CHUCK_REQUEST };
export const chuckSuccess = (joke) => { type: CHUCK_SUCCESS, joke };
export const chuckFailure = (err) => { type: CHUCK_FAILURE, err };
// controllers/index.js
import fetch from 'isomorphic-fetch'; // or whatever
import * as actions from '../actions';
const controllerGenerators = {
// ... other controller methods
*fetchAndSaveJoke() {
const { dispatch } = yield getProps;
// Trigger a reducer to set a loading state in your store, which the UI can key off of
dispatch(actions.chuckRequest());
try {
const response = yield fetch('jokes/random');
dispatch(actions.chuckSuccess(response.response.value.joke));
} catch(err) {
dispatch(actions.chuckFailure(err));
}
},
};
刚刚构建了我的第一个 API 中间件,只是想知道我应该在哪里为调度多个动作的动作创建者链接承诺。我做的是不是反模式:
export const fetchChuck = () => {
return {
[CALL_API]: {
types: [ CHUCK_REQUEST, CHUCK_SUCCESS, CHUCK_FAILURE ],
endpoint: `jokes/random`
}
}
}
export const saveJoke = (joke) => {
return { type: SAVE_JOKE, joke: joke }
}
export const fetchAndSaveJoke = () => {
return dispatch => {
dispatch(fetchChuck()).then((response) => {
dispatch(saveJoke(response.response.value.joke))
})
}
}
fetchAndSaveJoke 应该在我的 React 组件中分派 section 动作,还是可以将它作为自己的动作创建者?
我想说,在 Redux 世界的这一点上,还不是很清楚什么是最佳实践以及 anti-patterns 是什么。这是一个非常不拘一格的工具。虽然这对于多样化生态系统的蓬勃发展非常有利,但它确实给寻求组织应用程序的方法而不 运行 陷入陷阱或过多样板文件的人们带来了挑战。据我所知,您的方法似乎与 Redux 指南中的建议大致一致。对我来说有趣的一件事是 CHUCK_SUCCESS
似乎应该使 SAVE_JOKE
变得不必要。
我个人觉得让 action creator 派发更多的 action 很尴尬,所以我想出了 react-redux-controller 背后的方法。它是全新的,所以肯定不是 "best practice",但我会把它放在那里以防您或其他人想尝试一下。在该工作流程中,您将拥有一个类似于以下内容的控制器方法:
// actions/index.js
export const CHUCK_REQUEST = 'CHUCK_REQUEST';
export const CHUCK_SUCCESS = 'CHUCK_SUCCESS';
export const CHUCK_FAILURE = 'CHUCK_FAILURE';
export const chuckRequest = () => { type: CHUCK_REQUEST };
export const chuckSuccess = (joke) => { type: CHUCK_SUCCESS, joke };
export const chuckFailure = (err) => { type: CHUCK_FAILURE, err };
// controllers/index.js
import fetch from 'isomorphic-fetch'; // or whatever
import * as actions from '../actions';
const controllerGenerators = {
// ... other controller methods
*fetchAndSaveJoke() {
const { dispatch } = yield getProps;
// Trigger a reducer to set a loading state in your store, which the UI can key off of
dispatch(actions.chuckRequest());
try {
const response = yield fetch('jokes/random');
dispatch(actions.chuckSuccess(response.response.value.joke));
} catch(err) {
dispatch(actions.chuckFailure(err));
}
},
};