React.js中React-hook-form级联下拉选择功能失效问题求助
我来帮你排查下问题,你的代码里有几个关键问题导致联动失效,咱们一步步修复:
问题分析
- 没有用React状态管理城市列表:你用了普通变量
finalCities,React不会监听普通变量的变化,就算你更新了它,组件也不会重新渲染,城市下拉框自然不会跟着变。 - 错误的事件监听:下拉框的选择事件应该用
onChange,而不是onSelect——onSelect一般用于文本选择场景,不是下拉选项的触发事件。 - 第一个下拉框的option值错误:你写的
value={e.value},但你的州数据里根本没有value属性,应该用e.state(或者e.state_code,看你想把什么值存到表单里)。 - 城市下拉框渲染逻辑错误:
finalCities是对象数组,你直接把整个对象当option的value和显示文本,这肯定不对,得取city.name作为显示内容,city.code或者city.name作为value。
修复后的完整代码
import React, { useState } from "react"; import "../styles/App.scss"; import { useForm } from "react-hook-form"; import classNames from "classnames"; import arr from "../../src/data"; const StateCityDropdown = () => { const { register } = useForm(); // 用useState管理选中的州和对应的城市列表 const [selectedState, setSelectedState] = useState(""); const [cities, setCities] = useState([]); // 州选择变化时更新城市列表 const handleStateChange = (evt) => { const selected = evt.target.value; setSelectedState(selected); // 快速找到选中州对应的城市数据 const matchedState = arr.find(state => state.state === selected); setCities(matchedState ? matchedState.cities : []); }; return( <div> <div className="form-group"> <select className="custom-select" name="address.state" {...register("address.state")} value={selectedState} onChange={handleStateChange} > {/* 添加默认提示选项 */} <option value="">请选择州</option> {arr.map((state, key) => ( <option key={key} value={state.state}>{state.state}</option> ))} </select> </div> <div className="form-group"> <label htmlFor="City">City</label> <select className="custom-select" name="address.city" {...register("address.city")} {/* 没有选中州时禁用城市下拉,提升体验 */} disabled={cities.length === 0} > <option value="">请选择城市</option> {cities.map((city) => ( <option key={city.code} value={city.code}>{city.name}</option> ))} </select> </div> </div> ); }; export default StateCityDropdown;
修复关键点说明
- 用
useState创建了selectedState和cities两个状态,状态变化时React会自动重新渲染组件,保证城市列表实时更新。 - 把
onSelect换成了onChange,这是下拉框监听选择变化的标准事件。 - 修复了第一个下拉框的
option值,用state.state匹配后续的查找逻辑。 - 城市下拉框遍历
cities数组,取city.name作为显示文本,city.code作为value(你也可以根据需求换成city.name),同时添加了默认提示选项,还在无城市数据时禁用下拉框。 - 用
find代替forEach查找选中的州,效率更高——找到匹配项后就会停止遍历。
内容的提问来源于stack exchange,提问作者HiteshAgashe
相关产品推荐
相关产品推荐

