当编写redux-thunk
函数(称为 thunks )时,可以轻松地抽象掉一些样板文件。例如,在我们的大多数异步API调用中,我们正在执行以下操作,没有任何副作用:
export const LOGIN_REQUEST = 'my-app/auth/LOGIN_REQUEST';
export const LOGIN_RECIEVE = 'my-app/auth/LOGIN_RECIEVE';
export const LOGIN_FAILURE = 'my-app/auth/LOGIN_FAILURE';
// ... reducer code here
export function login(loginHandle, password) {
return (dispatch, getState, api) => {
dispatch({ type: LOGIN_REQUEST });
api.post('/auth/login', { loginHandle, password }).then(
response => dispatch({ type: LOGIN_RECIEVE, response }),
error => dispatch({ type: LOGIN_FAILURE, error })
);
};
}
轻松!虽然这至少覆盖了我们70%的请求,但我确信有一种优雅的方法可以将上述代码抽象为类似的内容(伪代码):
export function login(loginHandle, password) {
return (dispatch, getState, api) => api('POST', LOGIN_REQUEST, '/auth/login', { loginHandle, password });
}
当我们需要检查状态和其他副作用时,我们可以回到适当的thunk。虽然在大多数情况下......我们可以减少它吗?
任何优雅的想法?
答案 0 :(得分:8)
Redux Thunk允许您从2.1.0开始注入自定义参数。
const api = createApi() // you would write this function
const store = createStore(
reducer,
applyMiddleware(thunk.withExtraArgument(api))
)
// your action creator:
function fetchUser(id) {
return (dispatch, getState, api) => {
// you can use api here
}
}
将来,如果您的游戏过于复杂,您可能需要考虑redux-saga或redux-observable。
答案 1 :(得分:0)
不幸的是,在redux社区中没有通用的方法来解决这个问题。我个人认为人们不应该害怕在redux周围编写自己的自定义包装器来处理这种情况。
我创建了一个名为redux-tiles的库,它实际上具有您想要的几乎完全的API :)例如,您的代码将如下所示:
import { createTile } from 'redux-tiles';
const login = createTile({
type: ['user', 'login'],
// params is an argument with which you call an action
fn: ({ api, params }) => api('POST', '/auth/login', params),
});
如您所见,此处没有常量,还有减速器。这些东西是自动创建的,因此您不必执行此操作,也不必对其进行测试。还有其他功能,例如嵌套(因此,相同的功能将应用于通过id获取项目,但它们将在reducer内正确更新)和缓存。您可以查看示例here。
Redux-saga也是一件好事,但是如果你需要某种反应,如果你需要更传统的方法,只需要一点点方便的方式来描述你的行为并将它们结合起来,而不重复自己,那就更好了。然后我发现我的图书馆是一个完美的匹配。