【问题标题】:Chaining redux payload with axios使用 axios 链接 redux 有效负载
【发布时间】:2017-12-14 19:49:39
【问题描述】:

我正在使用 React 和 Redux(带有 promise 中间件和 thunk)为 WordPress 后端 (REST) 构建前端。

现在我正在使用 Redux 进行简单的调度以获取页面数据,例如:

export const fetchPostBySlug = (slug) => {
  return {
    type: "FETCH_MODULES",
    payload: axios.get(`${REST_URL}/wp/v2/posts?slug=${slug}`)
  }
}

现在我想做一个更复杂的调用。我想从 WordPress 中获取所有标签并返回这些标签。然后我获取所有特色标签。然后我获取所有具有特色标签的帖子。然后我获取所有具有特色标签的自定义帖子类型。

我的有效载荷最终应该是这样的:

payload: {
  id: 5,
  name: 'tag_5',
  slug: '/tag_5',
  tags: [all tags]
  posts: [all posts and cpt having a featured tag in here together]
}

这就是我现在所拥有的,它 fetches 基本上会获取所有内容,但还没有连接和分派。

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
    }
  }
}

【问题讨论】:

    标签: reactjs redux redux-thunk redux-promise-middleware


    【解决方案1】:

    由于您使用的是 thunk,因此您可以返回一个接受调度的函数,并使用该调度将有效负载发送到减速器。

    您也不需要 map 函数中的 if 语句,因为 map 不会循环遍历数组。事实上,在这种情况下使用 forEach 会更合适,因为我们没有返回任何内容。

    所以你的 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,
          });
        }))
    }

    【讨论】:

    • 实现了,谢谢。调用时获取TypeError: dispatch is not a function
    • 你能 console.log(dispatch) 告诉我它是否未定义吗?您是否正确使用了 applyMiddleware(例如 createStore 中的 applyMiddleware(thunkMiddleware))?最后,如何调用fetchTagPosts 函数?
    • 是的,它是undefined。这是我的中间件:const middelware = applyMiddleware(promise(), thunk, createLogger());export default createStore(reducer, middelware) 尝试以不同的方式调用该函数,一次在我初始化它的位置下方(在操作中),一次在组件的componentWillMount() 中,如下所示:this.props.dispatch(fetchTagPosts())
    • 搞定了。将this.props.dispatch(fetchTagPosts) 更改为fetchTagPosts(this.props.dispatched)。由于对象返回快速(空),因此必须在最后包含一个计数器。谢谢!
    猜你喜欢
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 2017-12-17
    • 1970-01-01
    • 2021-08-23
    相关资源
    最近更新 更多