我正在使用Redux Toolkit构建一个任务管理器应用程序来管理状态。板切片的initialState中的activeBoard属性。当我将其导入到编辑页面时,我可以编辑输入中的boardName属性,但不能编辑activeBoard对象中columns数组中的任何文本。我一直收到错误
“无法分配给对象的只读属性'board'
来自activeBoard对象的columns数组被传递到“columns”useState钩子。奇怪的是当我硬编码一个数组到useState钩子上时,我能够编辑每一列的输入。任何帮助都将不胜感激。
编辑板模式.jsx
import React, {useState} from 'react';
import {useDispatch, useSelector} from "react-redux";
import {editBoard} from "../../reducers/board/boardSlice";
import {hideModal} from "../../reducers/modal/modalSlice";
import Button from "../Button/Button";
import "./EditBoardModal.scss";
const EditBoardModal = () => {
const dispatch = useDispatch();
const {activeBoard} = useSelector(store => store.board);
const [boardName,
setBoardName] = useState(activeBoard.name);
const [columns,
setColumns] = useState([...activeBoard.columns]);
const nameChangeHandler = (e) => {
setBoardName(e.target.value)
}
const columnsChangeHandler = (i, e) => {
let columnsValues = [...columns];
columnsValues[i][e.target.name] = e.target.value;
console.log(columnsValues[0][e.target.name]);
setColumns(columnsValues);
}
return (
<div className="edit-board-modal">
<h3 className="edit-modal-title">Edit Board</h3>
<div className="edit-board-name-div">
<label>Board Name</label>
<input
value={boardName}
onChange={nameChangeHandler}
className="edit-task-title"
type="text"
name="edit board name"
placeholder="e.g. Web Design"/>
</div>
<div className="edit-board-columns-div">
<label>Board Columns</label>
{columns.map((column, index) => (
<div className="edit-columns-item-div" key={index}>
<input
onChange={e => columnsChangeHandler(index, e)}
className="edit-column-input"
type="text"
name="board"
value={column.board}
placeholder="e.g. Web Design"/>
<svg onClick={() => deleteColumn(index)} key={index} width="15" height="15" xmlns="http://www.w3.org/2000/svg">
<g fill="#828FA3" fillRule="evenodd"><path d="m12.728 0 2.122 2.122L2.122 14.85 0 12.728z"/><path d="M0 2.122 2.122 0 14.85 12.728l-2.122 2.122z"/></g>
</svg>
</div>
))}
</div>
<Button
onClick={() => dispatch(hideModal())}
text={"+ Add New Column"}
className={"add-column-subtask"}/>
<Button
onClick={() => {
dispatch(hideModal())
dispatch(editBoard(boardName));
}}
text={"Save Changes"}
className={"create-save-changes"}/>
</div>
)
}
export default EditBoardModal
板切片.js
import {createSlice} from "@reduxjs/toolkit";
const boardSlice = createSlice({
name: "board",
initialState: {
boards: [],
activeBoard: null
},
reducers: {
setActiveBoard: (state, {payload}) => {
const getBoardByID = state.boards.find(el => el.id === payload);
state.activeBoard = getBoardByID;
},
addBoard: (state, {payload}) => {
const newBoard = {
id: payload.id,
name: payload.name,
columns: payload.columns
}
if (state.boards.length === 0) {
state.activeBoard = newBoard;
}
state.boards.push(newBoard);
},
editBoard: (state, {payload}) => {
state.activeBoard.name = payload;
},
deleteCurrentBoard: (state, {payload}) => {
const deletedBoard = state.boards.filter(item => item.id !== state.activeBoard.id);
state.boards = deletedBoard;
state.activeBoard = state.boards[0];
},
addColumn: (state, {payload}) => {
state.activeBoard.columns.push(payload)
}
}
});
export const {
addBoard,
setActiveBoard,
deleteCurrentBoard,
addColumn,
editBoard
} = boardSlice.actions;
export default boardSlice.reducer;
2条答案
按热度按时间sxissh061#
columns
状态是activeBoard.columns
数组的浅层副本,但元素仍然是对切片中保存的原始数组的引用。columnsChangeHandler
函数也会建立columns
数组的浅层复本,但数组元素仍然是片段中原始数组的原始指涉。columnsChangeHandler
会尝试变更这些指涉。更新React状态时,必须浅复制正在更新得***所有**状态( 与嵌套状态 *).使用
Array.prototype.map
浅复制数组,并为匹配得索引创建新得对象引用,浅复制元素并重写相应得属性.示例:
u5rb5r592#
当您尝试变更已冻结对象的属性,或已使用Object定义属性时,通常会发生这个错误。
单击此处了解更多信息:https://bobbyhadz.com/blog/javascript-cannot-assign-to-read-only-property-of-object