React Hooks二级联动select下拉框切换一级选项后二级值未重置问题
问题根源
你当前实现的两个下拉框都是非受控组件,切换一级下拉时只更新了二级下拉的选项列表,没有主动重置二级下拉的选中状态。
React重渲染时会尽可能保留DOM原生状态:你之前选中a3时,select的selectedIndex停在了第4个选项的位置(索引从0计数,空选项为0、a1为1、a2为2、a3为3),切换到b的选项列表后,新列表长度和旧列表完全一致,索引3的位置刚好对应b3,因此会直接显示b3。这是React复用DOM、保留原生表单状态的默认行为,不是框架bug。
修复方案
把两个下拉框改成真正的受控组件,单独用state存储选中值,每次一级下拉切换时,同步把二级下拉的选中值重置为空字符串即可。
具体修改点
- 新增两个state分别存储一级、二级下拉的当前选中值,不要只存储选项列表
- 给两个select标签绑定
value属性对应选中值state,绑定onChange事件更新对应state - 一级下拉值变化时,除了更新二级下拉的选项列表,同步把二级下拉的选中值重置为空字符串
- 删掉代码中无用的空
useEffect和未被使用的DD1state
修正后的完整代码如下:
import React, { useState } from 'react'; import './App.css'; function Test_1() { // 单独存储下拉选中值,和选项列表状态分离 const [selected1, setSelected1] = useState(""); const [selected2, setSelected2] = useState(""); const [DD2Options, setDD2Options] = useState([]); const dd_data_1 = ["a", "b", "c"]; const dd_data_2 = [ {name: "a", content: "a1"}, {name: "a", content: "a2"}, {name: "a", content: "a3"}, {name: "b", content: "b1"}, {name: "b", content: "b2"}, {name: "b", content: "b3"}, {name: "c", content: "c1"}, {name: "c", content: "c2"}, {name: "c", content: "c3"} ]; const handleDD1Change = (e) => { const val = e.target.value; setSelected1(val); // 一级选项切换时,强制重置二级选中值为空 setSelected2(""); // 过滤对应二级选项 if (!val) { setDD2Options([]); return; } const options = dd_data_2.filter(x => x.name === val); setDD2Options(options); }; const handleDD2Change = (e) => { setSelected2(e.target.value); }; return ( <div id="main"> <select name="dd_1" id="dd_1" value={selected1} onChange={handleDD1Change} > <option value=""></option> {dd_data_1.map((x, i) => ( <option key={i} value={x}>{x}</option> ))} </select> <select name="dd_2" id="dd_2" value={selected2} onChange={handleDD2Change} > <option value=""></option> {DD2Options.map((x, i) => ( <option key={i} value={x.content}>{x.content}</option> ))} </select> </div> ) } export default Test_1;
补充说明
之前尝试改受控组件未生效,核心是漏了「切换一级选项时主动重置二级选中值」这一步——只给select加value属性但不在联动逻辑里主动重置值,React还是会沿用之前保留的选中状态。
实现表单联动时不要依赖DOM的selectedIndex默认行为,所有表单值都交给state托管,就不会出现这类状态不同步的问题。
内容的提问来源于stack exchange,提问作者Web Dev Newbie
相关产品推荐
相关产品推荐

