尝试在Redux-toolkit切片中存储一系列数组,但只得到一个

a0zr77ik  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(152)

我试图从数据库中取回一些数据,并将其Map到客户端中显示(使用react/redux-toolkit)。
数据的当前结构是一系列填充有对象的数组:

[
  {
    id: 2,
    prize_id: 1,
    book_id: 2,
    author_id: 2,
  }
]
[
  {
    id: 1,
    prize_id: 1,
    book_id: 1,
    author_id: 1,
  }
]

前端一次只显示一个数组,尽管需要同时显示两个数组。我认为问题出在我的redux是如何设置的。因为当我console.logaction.payload时,我只返回其中一个数组,通常是第二个。
下面是我的redux切片和操作的外观:
切片:

const booksSlice = createSlice({
  name: 'books',
  initialState: {
    booksByYear: [], //possibly the source of the problem
  },
  reducers: {},
  extraReducers: (builder) => {
    builder.addCase(actions.fetchBooksByYear.fulfilled, (state, action) => {
      console.log(action.payload)
      state.booksByYear = action.payload
    })
  },
})

处理措施:

export const fetchBooksByYear = createAsyncThunk(
  'books/get books by prize and year year',
  async ({ prizeId, prizeYear }) => {
    const data = await api.getBooksByPrizeAndYear(prizeId, prizeYear.year)
    return data
  }

下面是我从组件中获取数据的方法:
第一个
以前,它在调用was being made without redux时工作

ncecgwcz

ncecgwcz1#

所以booksByYear应该是数组的数组,对吗?例如:

booksByYear: [
  [
    {
      id: 2,
      prize_id: 1,
      book_id: 2,
      author_id: 2,
    }
  ],
  [
    {
      id: 1,
      prize_id: 1,
      book_id: 1,
      author_id: 1,
    }
  ]
]

切片设置看起来很好,我认为问题可能是api.getBooksByPrizeAndYear。因为builder.addCase回调中的action.payload是由对应的createAsyncThunk返回的,在本例中是fetchBooksByYear。因此,如果action.payload不是您所期望的,那么很有可能API一开始就没有响应正确的数据集。
我不确定你应用中的用例,如果API一次只返回一个数组,你可能想合并action.payloadstate.booksByYear,而不是替换它。
哦,现在我知道你为什么说initialState.booksByYear可能是问题了!是的,这是一个问题,因为从你的代码看,你似乎想按{ prizeYear, prizeId }对这些书进行“分组”,并在UI上显示每组中的书。由于目前只有一个数组,由于我们处理API响应(state.booksByYear = action.payload)的方式,最后完成的操作将始终覆盖先前完成的操作。
在这种情况下,我认为使用useState将这些书保留在组件中更有意义。但如果您真的想将这些书存储在redux中,可以尝试将initialState.booksByYear创建为一个类似Map的对象,并通过{ prizeYear, prizeId }<PrizeLists />中找到相应的数组。
例如:

// Slice
// You may want to implement the hash function that suits your case!
// This example may lead to a lot of collisions!
export const hashGroupKey = ({ prizeYear, prizeId }) => `${prizeYear}_${prizeId}`

const booksSlice = createSlice({
  name: 'books',
  initialState: {
    // We can't use Map here because it's non serializable.
    // key: hashGroupKey(...), value: Book[]
    booksMap: {}
  },
  extraReducers: (builder) => {
    builder.addCase(actions.fetchBooksByYear.fulfilled, (state, action) => {
      const key = hashGroupKey(action.meta.arg)
      state.booksMap[key] = action.payload
    })
  },
})

// PrizeLists
import { hashGroupKey } from '../somewhere/book.slice';

const listOfBooks = useSelector((state) => {
  const key = hashGroupKey(props)
  return state.books.booksMap[key] ?? []
})

相关问题