Redux Toolkit状态数组问题:如何为每个Box分配独立技能
解决方案:让每个Box拥有独立技能集合的Redux状态重构
问题根源在于当前Redux状态将所有Box的技能存储在全局数组中,未与具体Box(角色)关联,导致新增Box时技能被追加共享。要实现每个Box独立管理技能,需重构状态结构并调整Reducer动作:
1. 重构初始状态结构
把原来分散的角色信息和技能数组,拆分为临时表单数据(收集单个Box的输入)和角色列表(存储所有已创建的独立Box对象):
const initialState = { // 临时存储新增Box时的表单输入 tempRole: { name: "", description: "", requiredSkills: [], complimentarySkills: [], newRequiredSkill: "", // 单个必填技能的输入框值 newComplimentarySkill: "" // 单个补充技能的输入框值 }, // 存储所有已创建的Box,每个对象包含自身完整信息 roles: [] };
2. 更新Reducer动作
调整所有动作逻辑,让临时表单数据单独收集单个Box的信息,保存时将完整Box对象加入角色列表,同时清空临时数据:
const rolesSlice = createSlice({ name: "teamRoles", initialState, reducers: { // 设置临时角色名称 setTempRoleName: (state, action) => { state.tempRole.name = action.payload; }, // 设置临时角色描述 setTempRoleDescription: (state, action) => { state.tempRole.description = action.payload; }, // 设置临时必填技能输入框值 setTempNewRequiredSkill: (state, action) => { state.tempRole.newRequiredSkill = action.payload; }, // 设置临时补充技能输入框值 setTempNewComplimentarySkill: (state, action) => { state.tempRole.newComplimentarySkill = action.payload; }, // 往临时角色的必填技能数组添加技能(去重) addTempRequiredSkill: (state) => { const skill = state.tempRole.newRequiredSkill.trim(); if (skill && !state.tempRole.requiredSkills.includes(skill)) { state.tempRole.requiredSkills.push(skill); state.tempRole.newRequiredSkill = ""; // 清空输入框 } }, // 往临时角色的补充技能数组添加技能(去重) addTempComplimentarySkill: (state) => { const skill = state.tempRole.newComplimentarySkill.trim(); if (skill && !state.tempRole.complimentarySkills.includes(skill)) { state.tempRole.complimentarySkills.push(skill); state.tempRole.newComplimentarySkill = ""; // 清空输入框 } }, // 保存临时角色为独立Box,加入角色列表 saveRole: (state) => { const newRole = { ...state.tempRole }; if (newRole.name.trim()) { // 避免添加空角色 state.roles.push(newRole); // 清空临时表单数据,准备下一次新增 state.tempRole = { name: "", description: "", requiredSkills: [], complimentarySkills: [], newRequiredSkill: "", newComplimentarySkill: "" }; } } }, }); export const { setTempRoleName, setTempRoleDescription, setTempNewRequiredSkill, setTempNewComplimentarySkill, addTempRequiredSkill, addTempComplimentarySkill, saveRole } = rolesSlice.actions; export default rolesSlice.reducer;
3. 组件渲染调整
现在每个Box的技能都存储在对应角色对象的requiredSkills和complimentarySkills数组中,渲染时直接遍历roles数组即可:
{roles.map((role, index) => ( <div key={index} className="box"> <h3>{role.name}</h3> <p>{role.description}</p> <div className="skills"> <h4>必填技能:</h4> {role.requiredSkills.length > 0 ? ( role.requiredSkills.map((skill, idx) => ( <div key={idx} className="role__text-cont"> <p className="role__text">{skill}</p> </div> )) ) : <p>无</p>} {/* 补充技能渲染逻辑类似 */} <h4>补充技能:</h4> {role.complimentarySkills.length > 0 ? ( role.complimentarySkills.map((skill, idx) => ( <div key={idx} className="role__text-cont"> <p className="role__text">{skill}</p> </div> )) ) : <p>无</p>} </div> </div> ))}
关键修改说明
- 移除全局的
requiredSkill/complimentarySkill数组,改为每个角色对象自带独立技能集合 - 新增临时表单数据,单独收集每个Box的输入,避免不同Box的技能交叉污染
- 保存动作将完整的角色对象加入列表,确保每个Box的技能独立存储
内容的提问来源于stack exchange,提问作者Hassan Lasheen
相关产品推荐
相关产品推荐

