javascript Redux Toolkit状态对象未更改“未捕获的TypeError:无法分配给对象'# '的只读属性'property-name'< Object>”

ee7vknir  于 2022-10-30  发布在  Java
关注(0)|答案(1)|浏览(165)

我想更改状态对象的数据,但Redux Toolkit没有更改,并给出类似Uncaught TypeError: Cannot assign to read only property 'status' of object '#<Object>'的错误。
这些行来自组件:

const [width, setWidth] = useState(8)
  const [height, setHeight] = useState(9)
  const [table, setTable] = useState({
    rows: 
    [...Array(height)].map(()=>
      (
        {
          cells: 
            [...Array(width)].map(()=>
              (
                {status: true}
              )
            )
        }
      )
    )
  })

  useEffect(()=>{
    dispatch(changePlayableFields(table)) // <- it's not changing the state
  },[table])

  function changeCell(i:number,k:number){
    const localTable = {...table}
    localTable.rows[i].cells[k].status = !localTable.rows[i].cells[k].status // <-Uncaught TypeError: Cannot assign to read only property 'status' of object '#<Object>'
    setTable(localTable)
  }

changeCell函数运行得很好,我在页面上看到了真实结果。但是当添加useEffect代码来移动新数据以使用redux将它们保存在内存中时,我会得到错误。
这些来自Redux Slice:

import { createSlice } from "@reduxjs/toolkit"

const levelSlice = createSlice({
  name: "level",
  initialState: {
    gridSizeAndPlayableFields: {
      width: 8,
      height: 9,
      playableFields: {
        rows: 
        [...Array(9)].map(()=>
          (
            {
              cells: 
                [...Array(8)].map(()=>
                  (
                    {status: true}
                  )
                )
            }
          )
        )
      }
    },
  },
  reducers: {
    changePlayableFields: (state, action) => {
      state.gridSizeAndPlayableFields.playableFields = action.payload // <- it's not changing the data
    },
  }
})

export const {changeGridSize, changePlayableFields} = levelSlice.actions
export default levelSlice.reducer

这是关于我之前的问题的一点,也许你想检查一下。这里是我之前的问题链接:Redux Slice is returning an error after adding a function into a property of initial states
我希望任何人都能帮忙。谢谢...

8yoxcaq7

8yoxcaq71#

1.减速器未更新问题:

看起来你正在发送rows作为分派的有效负载。所以你应该更新reducer中的gridSizeAndPlayableFields.playableFields.rows

changePlayableFields: (state, action) => {
      // console.log(action.payload);
      state.gridSizeAndPlayableFields.playableFields.rows = action.payload.rows;
      // console.log(current(state.gridSizeAndPlayableFields.playableFields));
    },

2. changeCell方法中对象更新问题:

在一个普通的函数中,你不能像changeCell函数那样改变对象,你只能在redux工具包切片中这样做,这要归功于Immer
您可以对rowscells数组执行map操作,以更新相应索引的status值。您可以按以下方式编写changeCell方法:

function changeCell(i, k) {
    if (!table) return;
    const localTable = {};
    const localTableRows = [...table.rows];
    // map rows array
    const updatedRows = localTableRows.map((item, index) => {
      // if index equals i, map its cells as well
      //... and find kth cell and change its status
      if (index === i) {
        return {
          ...item,
          cells: item.cells.map((c, idx) => {
            if (idx === k) {
              return {
                ...c,
                status: !c.status,
              };
            }
            // if idx not equals to k return old cell item
            return c;
          }),
        };

      }
     // if index is not equal i return old row item
      return item;
    });
    localTable.rows = updatedRows;
    setTable(localTable);
  }

我假设ik是从零开始的数组的索引值。
您可以在您的changeCell函数中使用Object.reduce方法计算更新的表对象;但就我个人而言,我尽量避免这样做,因为一般来说,Object.reduce的性能较低。

相关问题