更新State导致数组渲染异常,按钮切换Mode失效求助
排查React切换mode后渲染异常的问题
问题背景
我在React组件里设置了4个按钮用来更新state中的mode字段:
<tr><button value = {0} name="mode" onClick={this.handleChange}>Montrer toutes les chambres</button></tr> <tr><button value = {1} name="mode" onClick={this.handleChange}>Montrer les chambres vides</button></tr> <tr><button value = {2} name="mode" onClick={this.handleChange}>Montrer les chambres avec de la place</button></tr> <tr><button value = {3} name="mode" onClick={this.handleChange}>Montrer les chambres pleines</button></tr>
对应的handleChange方法如下:
handleChange(event) { this.setState({[event.target.name] : event.target.value}); }
程序会根据mode的状态,基于数组myarray进行渲染:
let txt = myarray.map((item) => { console.log(this.state.mode); console.log(item); if(item===null) return(<div>Problème</div>); if(this.state.mode===0) return(<div>{item.info}</div>); else if ((this.state.mode===1)&& (b1)) return(<div>{item.info}</div>); else if((this.state.mode===2) && (b2)) return (<div>{item.info}</div>); else if((this.state.mode===3) && (b3)) return (<div>{item.info}</div>); else return(<div>Invalid item</div>); }); return txt;
程序启动时mode设为0,一切正常,但切换mode后所有项都返回"Invalid item"(即使切回mode=0也一样)。我已经将b1、b2、b3设为true测试仍无效,排除该因素,控制台日志显示的数值正确,怀疑是不是value的问题?
问题根源
这是个典型的类型不匹配问题!你踩了React按钮value属性的一个小坑:
- 初始时你把
mode设为数字0,所以this.state.mode===0这个严格相等判断是成立的; - 但按钮的
value属性在DOM中会被自动转换为字符串类型——哪怕你写的是{0},event.target.value拿到的实际是"0"(字符串); - 点击按钮后,state里的
mode就变成了字符串"0"、"1"等,这时候再用===和数字0、1比较,自然不相等,所有条件都不满足,就走到了最后的else分支返回"Invalid item"。
控制台日志看起来数值正确,是因为控制台会自动帮你做类型转换显示,但实际存储在state里的类型已经变了。
解决方案
有两种简单的修复方式,推荐第一种(保持类型一致是更好的代码实践):
方案1:将value转为数字后存入state
修改handleChange方法,把event.target.value转成数字类型:
handleChange(event) { this.setState({[event.target.name] : Number(event.target.value)}); }
方案2:修改判断条件为松散相等或字符串匹配
如果不想改动state的赋值逻辑,也可以把判断里的数字改成字符串,或者用松散相等==:
// 方式A:把判断值改成字符串 if(this.state.mode==="0") return(<div>{item.info}</div>); else if ((this.state.mode==="1")&& (b1)) return(<div>{item.info}</div>); // 方式B:用松散相等(不推荐,容易隐藏其他类型问题) if(this.state.mode==0) return(<div>{item.info}</div>); else if ((this.state.mode==1)&& (b1)) return(<div>{item.info}</div>);
第一种方案能从根源上保持state中mode的数字类型一致,避免后续其他逻辑再踩类型的坑,建议优先使用。
内容的提问来源于stack exchange,提问作者user10805364
相关产品推荐
相关产品推荐

