React表单存入state的数组length为0但存在元素如何解决
问题核心原因
你犯了两个关键错误,共同导致了这个现象:
- 类型使用错误:把普通对象的使用场景错用了数组
你初始化saveFormData为数组类型[],但实际使用时是给它添加字符串类型的键(比如ort),JS中数组的length属性仅统计下标为非负整数的元素,字符串键的自定义属性不会计入length,也不会被forEach()、JSON.stringify()等数组专属方法识别处理。 - 违反React State不可变原则
你直接修改了原state中saveFormData的属性,再把同一个引用塞回setState,这种写法不符合React的状态更新规范,可能会导致组件不触发重渲染等意料外的问题。
具体修复方案
1. 调整初始化类型
把saveFormData的初始值从空数组[]改为空对象{},你的需求是存储键值对结构,对象才是匹配的类型:
// constructor中修改 this.state = { // 其他属性保持不变 saveFormData: {} // 把[]改成{} }
2. 修正状态更新逻辑
不要直接修改原state的值,基于前序状态生成新对象再更新:
handleFormInput(event){ const target = event.target; const value = target.type === 'checkbox' ? target.checked : target.value; const name = target.name; // 不要直接修改原state,生成新对象 this.setState(prevState => ({ saveFormData: { ...prevState.saveFormData, [name]: value } }), () => {console.log(this.state.saveFormData)}); }
3. 修正提交时的判断逻辑
用对象的键集合长度来判断是否有数据:
handleForm(){ // 取对象所有键的长度判断是否有值 const formDataLength = Object.keys(this.state.saveFormData).length; console.log(formDataLength); // 输入内容后就会得到对应的数量,不再是0 if(formDataLength == 0){ this.setState({ openNew: false }) console.log(this.state.saveFormData); }else{ console.log(this.state.saveFormData); alert('we found Data' + JSON.stringify(this.state.saveFormData)); } }
控制台现象说明
你看到的控制台输出不是引用快照问题,是真实的数据结构:数组本身也是JS对象的一种,支持添加自定义属性,这些属性不会改变数组的length值,所以你展开数组能看到ort属性,但length确实为0,属于JS的基础语法特性。
内容的提问来源于stack exchange,提问作者Maik Thiele
相关产品推荐
相关产品推荐

