React useReducer Hook及Reducer函数实现组件增删时删除功能异常求助
问题排查与修复方案
核心问题原因
- 存储结构错误:你往reducer里存的是
<Note />React元素实例,不是带id属性的普通数据对象,component.id永远返回undefined,导致匹配逻辑完全失效。对应你遇到的现象:当用component.id == action.payload时,undefined == 数字永远为false,filter会过滤掉所有项,表现为所有组件都被删除;改用!==时undefined !== 数字永远为true,所有项都被保留,表现为删不掉任何组件 - setId异步更新问题:
newComponent方法中先调用setId更新状态,后续马上读取的id还是上一次的旧值,不是刚生成的随机id - 删除逻辑条件写反:filter方法保留的是返回true的项,删除指定id应该保留不等于目标id的项,正确条件是
id !== action.payload
修复步骤
第一步:调整存储结构,不要直接存React组件
修改NewComponentMenu中的新增逻辑,生成元数据而非直接传组件:
const NewComponentMenu = () => { const { addComponent } = useContext(NewComponentContext) // 删掉原本存id的state,不需要了 const newComponent = () => { // 先生成id,不要依赖异步更新的state const newId = Math.floor(Math.random() * 100000000) // 往reducer里存元数据,不是组件 addComponent({ id: newId, type: 'note' // 后续加Todo/Photo可以通过type区分 }) } return ( {/* 其他代码不变,只改点击事件 */} <li onClick={() => newComponent()} {/* 其他属性不变 */} > {/* 其余代码不变 */} ) }
第二步:修正reducer逻辑
export default function reducer(state: any, action: any) { switch (action.type) { case "ADD_COMPONENT": return { ...state, components: [...state.components, action.payload], }; case "DELETE_COMPONENT": return { ...state, // 保留不等于目标id的项 components: state.components.filter( (item) => item.id !== action.payload ), }; default: return state; } }
第三步:渲染组件时动态生成
在你遍历components数组渲染的页面,根据元数据生成对应组件:
// 示例:你渲染动态组件的页面代码 const { components } = useContext(NewComponentContext) return ( <div> {components.map(item => { if (item.type === 'note') { return <Note key={item.id} id={item.id} /> } // 后续加Todo/Photo的判断逻辑即可 return null })} {/* 其他页面元素 */} </div> )
内容的提问来源于stack exchange,提问作者ckam03
相关产品推荐
相关产品推荐

