redux React还原类型错误:无法添加property _,对象不可扩展

x33g5p2x  于 2023-03-18  发布在  React
关注(0)|答案(1)|浏览(238)

这个网站允许用户存储链接的集合,每个集合都有多极类别,每个类别可以有多个条目:

import { createSlice, current } from '@reduxjs/toolkit';
import { Categories, Collection } from '../TestData';
import {RandomId} from '../util/RandomId'

let categoryList = Categories

const categorySlice = createSlice({
  name: 'category',
  initialState: {
    value: categoryList,
    currentCollectionId: Collection[0].collectionId
  },
  reducers: {
    // Retrieve categories corresponding to collectionId
    getCategories: (state, { payload }) => {
      const collectionId = payload
      const latestCatList = []

      // Find the categories corresponding with the collectionId
      categoryList.map((item) => {
        if (item.collectionId === collectionId) {
          latestCatList.push(item)
        }
      })
      //Update the category list the categories
      state.value = [...latestCatList]
      //Update the current collectionId state
      state.currentCollectionId = collectionId
      return state
    },
    // Add new category
    addCategory: (state, { payload }) => {
      const newCategory = {
        collectionId: state.currentCollectionId,
        catId: RandomId(),
        name: payload.name,
        listEntries: payload.listEntries
      }
      state.value.push(newCategory) // Add new category object to state
      state.value = [...state.value]
            
      // NEED TO ADD CATEOGRY TO TEST DATA BUT FOR SOME GODDAMN REASON ITS NOT, maybe push to database straight instead
      categoryList.push(newCategory)
    },
  }   
})

我使用react-redux,在一个组件中,当我点击一个按钮时,它调用addCategory动作,我在另一个文件中有一个Category对象数组,我像这样导出和导入到这个文件中,所以我这样做的主要方法是,我必须在另一个文件中存储整个类别列表(我将使用后端拉必要的类别关联到每个用户),因为有些类别可能与不同的集合绑定,所以我有一个getCategories简化器,它可以根据当前的集合检索适当的Categories所以每次添加category时,我都需要添加到当前状态以及另一个文件中的Categories数组:
但由于某种原因,当我试图将新对象推送到原始类别数组时,它会给出此错误:
错误:

categorySlice.js:36 Uncaught TypeError: Cannot add property 3, object is not extensible
at Array.push (<anonymous>)
at addCategory (categorySlice.js:36:1)
at createReducer.ts:294:1
at produce (immerClass.ts:94:1)
at createReducer.ts:293:1
at Array.reduce (<anonymous>)
at reducer (createReducer.ts:260:1)
at reducer (createSlice.ts:372:1)
at combination (redux.js:560:1)
at E (<anonymous>:1:33326)

下面是类别数组:

export const Categories = [
  {
    collectionId: '1232', // Reference the collection the categories are under
    catId: '1232019283',
    name: 'FIT 2099', // Name of category
    listEntries: [ // Array of objects for each list entry
      {
        name: 'Assignment 1',
        link: 'Ed forums FIT 2099_ A1'
      },
      {
        name: 'Assignment 2',
        link: 'Ed forums FIT 2099_ A2'
      },
    ] 
  },
  {
    collectionId: '1232',
    catId: '1232120398',
    name: 'FIT 2004',
    listEntries: [
      {
        name: 'Tutorial 2',
        link: 'Master theore,'
      }
    ]
  },
  {
    collectionId: '1231',
    catId: '123109101',
    name: 'Movie List',
    listEntries: [
      {
        name: 'Harry potter 1',
        link: 'Hurawatch HP 1'
      }
    ] 
  },
]

我做了一些搜索,我没有调用preventExtensions的任何地方,所以是自动调用它的东西吗?但有道理,我尝试甚至只是复制数组使用传播运算符或改变constvar没有工作。

wqnecbli

wqnecbli1#

你在那里做的事情肯定不安全--你的减速器有副作用。
这个reducer完全可以用相同的stateaction运行100次。从Redux的Angular 来看,action只会发生一次,因为无论你多久执行一次reducer,它总是返回相同的结果。
但是,由于您将数据保存到categoryList的旁边,因此最终会有100个值。
更糟糕的是,这在某种程度上是你状态的一部分,而在某种程度上不是。这里的reducer运行immer,它用一个草稿副本替换你的整个对象,然后“密封”结果,这样它就不能再被更改了。正如你所发现的,在这个过程中“取出”一些东西,然后在以后的时间访问它可能是灾难性的。
你必须保持你的还原剂的纯度。你在这里所做的是行不通的。
你一开始为什么要这么做?这看起来很可行。

相关问题