useState修改对象内数组后未触发React组件重新渲染如何解决
问题原因
核心错误有3处:
- 直接修改原有state的引用,没有生成新的引用值:React对state更新做浅比较,也就是只对比前后state的引用地址是否变化。你代码里
const updatedFormValue = formValue只是把原state的引用赋值给新变量,后续push操作也是直接修改原有aliases数组,没有创建新的对象和数组,所以React检测不到state变化,不会触发重渲染。这也是为什么你在React DevTools能看到state值更新,但页面不会刷新的原因。 - 维护了冗余的重复state:
formValue已经包含aliases属性,不需要单独声明formAliases存储同一份数据,容易出现数据不一致的问题。 - 代码存在语法错误:
Accordion组件标签错误自闭合,且多了多余的}符号;formAliases.map的返回值是对象而非可渲染的内容,就算触发重渲染也无法正常展示别名。
修复方案
修改后的代码如下:
import Accordion from "@components/common/Accordion" import Alias from "./value-form/Alias" import { useDispatch, useState } from 'react' // 请替换为你实际的样式文件、Button组件导入路径 import styles from './styles.module.css' import Button from "@components/common/Button" const ValueItem = props => { const { value } = props const dispatch = useDispatch() // 仅保留一份formValue state即可 const [formValue, setFormValue] = useState(value) const addAlias = () => { // 生成新的对象、新的数组引用,React才能检测到更新 setFormValue({ ...formValue, aliases: [...formValue.aliases, ""] }) } return ( <Accordion key={value.id} title={value.name} > <div className={styles.valueFormContainer}> {/* 遍历返回可渲染节点,每项添加唯一key */} {formValue.aliases.map((alias, index) => { return <div key={index}>{alias}</div> })} <Button handleChange={addAlias} buttonLabel="+ Add Alias" buttonTypes={["orange"]} /> </div> </Accordion> ) } export default ValueItem
额外注意
- 如果后续需要支持别名的编辑、删除操作,不要用数组下标作为map的key,建议给每个别名项生成唯一ID作为key,避免渲染异常。
- 如果props传入的
value会动态更新,需要添加useEffect监听value变化同步更新内部formValue,避免props更新后内部state还是旧值。
内容的提问来源于stack exchange,提问作者DLateef
相关产品推荐
相关产品推荐

