使用 axios 链接 redux payload
Chaining redux payload with axios
我正在为 WordPress 后端 (REST) 使用 React 和 Redux(带有 promise 中间件和 thunk)构建前端。
现在我正在使用 Redux 进行简单的调度以获取页面数据,例如:
export const fetchPostBySlug = (slug) => {
return {
type: "FETCH_MODULES",
payload: axios.get(`${REST_URL}/wp/v2/posts?slug=${slug}`)
}
}
现在我想做一个更复杂的调用。我想从 WordPress 和 return 中获取所有标签。然后我获取所有特色标签。然后我获取所有具有特色标签的 post。然后我获取所有具有特色标签的自定义 post 类型。
我的有效负载最终会像这样:
payload: {
id: 5,
name: 'tag_5',
slug: '/tag_5',
tags: [all tags]
posts: [all posts and cpt having a featured tag in here together]
}
这就是我现在所拥有的,它基本上可以获取所有内容,但还没有连接和分派。
const fetchTagPosts = () => {
axios.all([fetchAllTags(), fetchFeaturedTopics()])
.then(axios.spread((all, featured) => {
let payload = {}
const ft = featured.data.featured_tags
const ft_length = ft.length
ft.map((x, i) => {
getPostsByTag(x.term_id).then(y => payload = addPostToPayload(y.data, x.term_id, payload))
getCPTByTag(x.term_id).then(y => payload = addPostToPayload(y.data, x.term_id, payload))
// I need to check here if both are loaded, so I can concat the arrays
if (ft_length === i + 1) {
// I need to dispatch/return the payload here
}
})
}))
}
const addPostToPayload = (p, id, payload) => {
return {
[id]: {
posts: payload[id] ? payload[id].posts.concat(p) : p
}
}
}
由于您使用的是 thunk,因此您可以 return 接受分派的函数并使用该分派将有效负载发送到 reducer。
您也不需要 map 函数中的 if 语句,因为 map 不会遍历数组。事实上,在这种情况下使用 forEach 会更合适,因为我们没有 returning 任何东西。
因此您的 fetchTagPosts 将如下所示:
const fetchTagPosts = (dispatch) => {
axios.all([fetchAllTags(), fetchFeaturedTopics()])
.then(axios.spread((all, featured) => {
let payload = {}
const ft = featured.data.featured_tags
// loop through ft
ft.forEach(x => {
getPostsByTag(x.term_id).then(y => payload = addPostToPayload(y.data, x.term_id, payload))
getCPTByTag(x.term_id).then(y => payload = addPostToPayload(y.data, x.term_id, payload))
});
// dispatch payload to reducer
dispatch({
type: 'FETCH_TAG_POSTS',
payload,
});
}))
}
我正在为 WordPress 后端 (REST) 使用 React 和 Redux(带有 promise 中间件和 thunk)构建前端。
现在我正在使用 Redux 进行简单的调度以获取页面数据,例如:
export const fetchPostBySlug = (slug) => {
return {
type: "FETCH_MODULES",
payload: axios.get(`${REST_URL}/wp/v2/posts?slug=${slug}`)
}
}
现在我想做一个更复杂的调用。我想从 WordPress 和 return 中获取所有标签。然后我获取所有特色标签。然后我获取所有具有特色标签的 post。然后我获取所有具有特色标签的自定义 post 类型。
我的有效负载最终会像这样:
payload: {
id: 5,
name: 'tag_5',
slug: '/tag_5',
tags: [all tags]
posts: [all posts and cpt having a featured tag in here together]
}
这就是我现在所拥有的,它基本上可以获取所有内容,但还没有连接和分派。
const fetchTagPosts = () => {
axios.all([fetchAllTags(), fetchFeaturedTopics()])
.then(axios.spread((all, featured) => {
let payload = {}
const ft = featured.data.featured_tags
const ft_length = ft.length
ft.map((x, i) => {
getPostsByTag(x.term_id).then(y => payload = addPostToPayload(y.data, x.term_id, payload))
getCPTByTag(x.term_id).then(y => payload = addPostToPayload(y.data, x.term_id, payload))
// I need to check here if both are loaded, so I can concat the arrays
if (ft_length === i + 1) {
// I need to dispatch/return the payload here
}
})
}))
}
const addPostToPayload = (p, id, payload) => {
return {
[id]: {
posts: payload[id] ? payload[id].posts.concat(p) : p
}
}
}
由于您使用的是 thunk,因此您可以 return 接受分派的函数并使用该分派将有效负载发送到 reducer。
您也不需要 map 函数中的 if 语句,因为 map 不会遍历数组。事实上,在这种情况下使用 forEach 会更合适,因为我们没有 returning 任何东西。
因此您的 fetchTagPosts 将如下所示:
const fetchTagPosts = (dispatch) => {
axios.all([fetchAllTags(), fetchFeaturedTopics()])
.then(axios.spread((all, featured) => {
let payload = {}
const ft = featured.data.featured_tags
// loop through ft
ft.forEach(x => {
getPostsByTag(x.term_id).then(y => payload = addPostToPayload(y.data, x.term_id, payload))
getCPTByTag(x.term_id).then(y => payload = addPostToPayload(y.data, x.term_id, payload))
});
// dispatch payload to reducer
dispatch({
type: 'FETCH_TAG_POSTS',
payload,
});
}))
}