React中如何使用useState钩子更新状态对象的数组属性
实现方法
首先用useState按照你给出的初始结构初始化状态即可,核心注意点是:React状态更新遵循不可变原则,更新嵌套在对象里的skills数组时,必须先拷贝原对象的其余属性(比如这里的name字段),避免字段丢失,同时不能直接修改原状态里的数组,否则不会触发组件重渲染。
基础状态初始化
import { useState } from 'react' // 初始化状态 const [userInfo, setUserInfo] = useState({ name: "lorem ipsum", skills: [] })
不同场景的更新逻辑
- 单个技能逐个追加:适用于用户每输入一个技能点添加按钮,就把技能追加到列表的场景
const handleAddSingleSkill = (newSkill) => { // 空内容直接拦截,不加入列表 if (!newSkill.trim()) return setUserInfo(prevState => ({ // 展开原状态所有属性,保证name等非skills字段不丢失 ...prevState, // 生成新的skills数组:拷贝原有技能,追加新技能 skills: [...prevState.skills, newSkill.trim()] })) }
- 批量录入一次性更新:适用于用户一次性选完/输完所有技能,整体提交替换技能列表的场景,你举的HTML、CSS、JavaScript三项录入的例子就可以用这个逻辑
const handleUpdateAllSkills = (submittedSkillList) => { setUserInfo(prevState => ({ ...prevState, // 直接将提交的技能列表作为新的skills值即可 skills: submittedSkillList })) } // 调用示例:更新后就是你给出的目标结构 handleUpdateAllSkills(['html','css','JavaScript'])
简单可运行的表单示例
function SkillEntryForm() { const [userInfo, setUserInfo] = useState({ name: "lorem ipsum", skills: [] }) const [currentInput, setCurrentInput] = useState('') const handleAddClick = () => { if (!currentInput.trim()) return setUserInfo(prev => ({ ...prev, skills: [...prev.skills, currentInput.trim()] })) setCurrentInput('') // 添加完成后清空输入框 } return ( <div> <p>当前用户:{userInfo.name}</p> <div> <input type="text" value={currentInput} onChange={e => setCurrentInput(e.target.value)} placeholder="输入技能名称" /> <button onClick={handleAddClick}>添加技能</button> </div> <p>已录入技能列表:{userInfo.skills.join('、')}</p> </div> ) }
避坑提醒:不要直接修改原状态,比如直接调用
userInfo.skills.push(xxx)再执行setState是错误写法,直接突变原状态会导致组件不触发重渲染,还会引发状态不一致的问题,所有更新都要传给setState一个全新的对象/数组。
内容的提问来源于stack exchange,提问作者TechyGeek1707
相关产品推荐
相关产品推荐

