首页 > 解决方案 > 在 createAsyncThunk 方法中覆盖对象属性

问题描述

我有这样的功能

export const fetchChildrenNews = createAsyncThunk('news/fetch1', async ([item, news]) => {
      const res = await Promise.all(item.kids.map(id => {
        let url = `https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`;
        return fetch(url);
      }));
      const jsons = await Promise.all(res.map(r => r.json()));
      let users = {...item, kids: jsons};
      item.kids = []//doesn't work
      item.id = 0 //doesn't work

      //I want to find a branch in the original tree and replace it

      const tree = (obj) => {
          for (let key in obj) {
              if (key === "id" && obj[key] === users.id) {
                obj = users;
              }

              if (key == "kids") {
                tree(obj);
              }
          }
      }

      tree(item);

其中 item 是嵌套对象记录:{by: 'nullzzz', descendants: 47, id: 28808556, kids: Array(13), score: 117}。kids 属性包含 id 数组,在 users 变量中它变成了一个记录数组。我的目标将 record.kids = [0, 7, 14] 更改为 record.kids = users ([{by: '...', id:4848,..], [{by: 'adasd'], [ {作者:'zzz}])。变量 news 是一整棵树,而 item 是它的分支。我刚开始使用工具包,所以我不完全理解这一点

标签: redux-toolkit

解决方案


由于item可能是来自您的 Redux 存储的对象,因此该 thunk 会尝试修改对您的存储的引用 - 并且仅在减速器中允许修改存储。

一般来说,你应该在 reducer 中做这样的逻辑,而不是在一个 thunk 中。

所以,做

export const fetchChildrenNews = createAsyncThunk('news/fetch1', async ([item, news]) => {
      const res = await Promise.all(item.kids.map(id => {
        let url = `https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`;
        return fetch(url);
      }));
      const jsons = await Promise.all(res.map(r => r.json()));
      return jsons
})

然后在你的切片中,添加逻辑:

builder.addCase(fetchChildrenNews, (state, action) => {
  const jsons = action.payload

  // here, do not modify `items`, but modify `state` - I would assume `items` is somewhere in here anyways?
})

推荐阅读