React删除组件后状态错乱求助:删除id=2后id=3值异常
问题原因分析
- 列表渲染缺少唯一key:你在
idArray.map渲染Component时未指定key属性,React默认用数组索引作为key。删除id=2的项后,原数组变为[1,3],map遍历索引0对应id=1、索引1对应id=3,但React会复用原索引1的组件实例(即之前id=2的组件),该组件的状态仍为val2,因此出现id=3的输入显示val2的错位问题。 - 状态分散存储:每个
Component单独维护description局部状态,未将状态与对应id绑定到全局状态中,导致组件复用时,状态无法匹配正确的id。
解决方法
1. 为列表项添加唯一key
在map渲染Component时,将id作为key传入,让React精准识别每个组件实例:
let components = idArray.map((id) => { return ( <Component key={id} id={id} /> ); })
2. 统一管理所有输入状态
将所有输入框的值存入全局Context的状态中,以id为键建立映射,替代组件局部状态。
调整Context状态结构
更新Context的初始状态,新增values对象存储每个id对应的输入值:
const initialState = { idArray: [], values: {}, setIdArray: () => {}, setValues: () => {} };
修改Display组件
引入全局values状态,同时用React状态管理count(避免全局变量的不可预测性):
export default function Display() { const { idArray, setIdArray, values, setValues } = useContext(Context); const [count, setCount] = useState(1); let components = idArray.map((id) => { return ( <Component key={id} id={id} /> ); }); const handleFirstInputChange = ({ detail }) => { setValues(prev => ({ ...prev, 1: detail.value })); }; return ( <> <div id="component-1"> <input className="className" id="1" type="text" onChange={handleFirstInputChange} value={values[1] || ""} placeholder="Enter description" /> {components} </div> <button iconName="add-plus" onClick={() => { const newCount = count + 1; setCount(newCount); setIdArray(previousIdArray => [...previousIdArray, newCount]); setValues(prev => ({ ...prev, [newCount]: "" })); }} /> </> ); }
修改Component组件
移除局部description状态,直接使用全局values,修改时同步更新全局状态:
export default function Component(props) { const { idArray, setIdArray, values, setValues } = useContext(Context); const { id } = props; function removeRow() { const newArray = idArray.filter((i) => i !== id); setIdArray(newArray); setValues(prev => { const newValues = { ...prev }; delete newValues[id]; return newValues; }); } const handleInputChange = ({ detail }) => { setValues(prev => ({ ...prev, [id]: detail.value })); }; return ( <div id={id}> <input className="className" id={id} type="text" onChange={handleInputChange} value={values[id] || ""} placeholder="Enter description" /> <button iconName="cross" onClick={removeRow} /> </div> ); }
补充说明
- 用
useState管理count替代全局变量,确保组件重新渲染时count状态可靠,避免多实例下的冲突。 - 统一状态管理后,每个输入框的值与id绑定,删除操作仅移除对应id的状态,彻底解决状态错位问题。
内容的提问来源于stack exchange,提问作者Shaurya Atri
相关产品推荐
相关产品推荐

