我有一个使用redux thunk的动作,看起来像这样:
export function fetchData(query) {
return dispatch => {
return fetch(`http://myapi?query=${query}` ,{mode: 'cors'})
.then(response => response.json())
.then(json => { dispatch(someOtherAction(json)) })
}
}
}
然后我的someOtherAction
实际更新状态:
export function someOtherAction(data) {
return {
action: types.SOME_ACTION,
data
}
}
但是我希望fetchData
动作创建者可以重复使用,以便我的应用的不同部分可以从myapi
获取数据,然后根据该部分拥有状态的不同部分。
我想知道重用此操作的最佳方法是什么?是否可以将第二个参数传递给我的fetchData
动作创建者,该参数规定了成功获取时调用的动作:
export function fetchData(query, nextAction) {
return dispatch => {
return fetch(`http://myapi?query=${query}` ,{mode: 'cors'})
.then(response => response.json())
.then(json => { dispatch(nextAction(json)) })
}
}
}
或者有没有可以接受的做这种事情的方式?
答案 0 :(得分:1)
我使用中间件。我已经在那里定义了fetch调用,然后在我的操作中,我将URL发送到fetch以及完成后调度的操作。这将是典型的获取操作:
const POSTS_LOAD = 'myapp/POST_L';
const POST_SUCCESS = 'myapp/POST_S';
const POST_FAIL = 'myapp/POST_F';
export function fetchLatestPosts(page) {
return {
actions: [POSTS_LOAD, POST_SUCCESS, POST_FAIL],
promise: {
url: '/some/path/to/posts',
params: { ... },
headers: { ... },
},
};
}
调用该操作时,中间件将在执行获取请求之前自动调度POST_LOAD
操作。如果一切顺利,将使用json响应调度POST_SUCCESS
操作,如果出现问题,中间件将调度POST_FAIL
操作。
中间件中的所有魔力!它与此类似:
export default function fetchMiddleware() {
return ({ dispatch, getState }) => {
return next => action => {
if (typeof action === 'function') {
return action(dispatch, getState);
}
const { promise, actions, ...rest } = action;
if (!promise) {
return next(action);
}
const [REQUEST, SUCCESS, FAILURE] = actions;
next({ ...rest, type: REQUEST }); // <-- dispatch the LOAD action
const actionPromise = fetch(promise.url, promise); // <-- Make sure to add the domain
actionPromise
.then(response => response.json())
.then(json => next({ ...rest, json, type: SUCCESS })) // <-- Dispatch the success action
.catch(error => next({ ...rest, error, type: FAILURE })); // <-- Dispatch the failure action
return actionPromise;
};
};
}
这样我就可以在一个地方完成所有请求,并且可以在请求完成后定义要运行的操作。
<强> ------------ ---------------- EDIT 强>
要获取reducer上的数据,您需要使用在原始操作创建者上定义的操作名称。以下示例说明如何处理来自中间件的POST_SUCCESS
操作,以从posts
响应中获取json
数据。
export function reducer(state = {}, action) {
switch(action.type) {
case POST_SUCCESS: // <-- Action name
return {
...state,
posts: action.json.posts, // <-- Getting the data from the action
}
default:
return state;
}
}
我希望这有帮助!