React修改state中对象className属性返回异常字符数组如何解决
存在的问题
changeClass方法中Object.assign的使用完全错误:prev是inputAll对应的数组类型旧值,你直接尝试给数组本身添加className属性,而非修改数组内的待办对象属性。同时你传入Object.assign的参数语法非法,最终导致字符串drop-list delete被拆分为按索引存储的字符对象,就是你控制台看到的错误结果。- 事件绑定逻辑错误:
onClick={changeList(inputAll)}会在组件渲染时直接执行函数,而非点击时触发,且函数名拼写错误(定义的是changeClass,调用写的是changeList)。 - 渲染遍历的数据源错误:你新增的待办数据存在
inputAll中,但return里遍历的是空数组input,不会渲染出你添加的待办项。 - state更新是异步的,
setInputAll执行后马上打印inputAll拿到的是更新前的旧值,无法看到最新状态。
修复方案
修改changeClass逻辑:先遍历旧数组,找到对应要修改的待办项,生成新的对象修改className后返回新数组;修正事件绑定为箭头函数包裹,传入当前待办项的id作为匹配标识;修正遍历的数据源为inputAll,补充map渲染必须的key属性。
修复后完整代码:
import { useState, useEffect } from 'react' const Todo = () => { const [inputAll, setInputAll] = useState([]) // input用于存储输入框内容,改为字符串类型更符合使用场景 const [input, setInput] = useState('') const addList = () => { const newListItem = { id: inputAll.length + 1, value: input || 'go home', className: 'drop-list' } setInputAll([...inputAll, newListItem]) // 新增后清空输入框 setInput('') } const changeClass = (taskId) => { const newClass = 'drop-list delete' setInputAll((prev) => { // 遍历旧数组,只修改匹配id的待办项 return prev.map(item => { if (item.id === taskId) { // 返回新对象,避免直接修改原state return {...item, className: newClass} } return item }) }) } // 监听inputAll变化打印最新值 useEffect(() => { console.log(inputAll) }, [inputAll]) return ( <> {/* 绑定输入框内容到input状态 */} <input type="text" value={input} onChange={(e) => setInput(e.target.value)} /> {inputAll.map(item => { return ( <div className="todo-row" key={item.id}> <span className="todo-value">{item.value}</span> <span> <button className="btn btn-success" onClick={addList}>Add</button> <button className="btn btn-danger" onClick={() => changeClass(item.id)}>Change</button> </span> </div> ) })} </> ) }
内容的提问来源于stack exchange,提问作者Ajayi Michael
相关产品推荐
相关产品推荐

