如何在React表单中传递独立组件下拉框的选中值
解决方案
问题核心是下拉框组件的状态被自身独立维护,父表单组件无法获取其选中值,通过「状态提升」和「受控组件改造」就能解决:
步骤1:改造父表单组件(AddSensor)
将传感器类型的状态提升到表单组件中,并传递给下拉框组件:
import { useState } from 'react'; import { SensorTypeDropdown } from '../add/SensorTypeDropdown' import { SharedAmbientSurrounding } from "@libs/data"; // 导入枚举类型 const AddSensor = () => { const [imei, setImei] = useState(''); // 添加传感器类型状态,初始值和下拉框默认值保持一致 const [sensorType, setSensorType] = useState<SharedAmbientSurrounding>(SharedAmbientSurrounding.TEMPERATURE); const handleSubmit = (event: any) => { // 现在可同时获取IMEI和传感器类型 alert(`Sensor with IMEI: ${imei}, Type: ${sensorType} created.`); event.preventDefault(); setImei(''); // 重置下拉框选中值 setSensorType(SharedAmbientSurrounding.TEMPERATURE); } return ( <div className="container mx-auto"> <form className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4" onSubmit={handleSubmit}> <div className="mb-4"> <label className="block text-sm font-bold mb-2" htmlFor="imei"> IMEI </label> <input className="border rounded w-full py-2 px-3 focus:shadow-outline focus:outline-sky-700" value={imei} onChange={event => setImei(event.target.value)} id="imei" // 修正id与label的htmlFor对应 /> </div> <div className="mb-6"> <label className="block text-sm font-bold mb-2" htmlFor="sensorType"> Sensor type </label> {/* 传递状态和更新回调给下拉框 */} <SensorTypeDropdown value={sensorType} onChange={setSensorType} /> </div> <div className="flex items-center justify-between"> <input type="submit" className="cursor-pointer bg-sky-700 hover:bg-sky-800 text-white font-bold py-2 px-4 rounded focus:shadow-outline" value="Create sensor" /> </div> </form> </div> ) } export default AddSensor;
步骤2:改造下拉框组件(SensorTypeDropdown)
将其改为受控组件,不再维护内部状态,完全依赖父组件传递的props:
import { SharedAmbientSurrounding } from "@libs/data"; import { getEnumKeys } from "../../helpers/getEnumKeys"; // 接收父组件传递的value和onChange回调 export const SensorTypeDropdown = ({ value, onChange }: { value: SharedAmbientSurrounding, onChange: (type: SharedAmbientSurrounding) => void }) => { return ( <select value={value} onChange={(e) => { // 将选中的枚举值传递给父组件的回调 const selected = SharedAmbientSurrounding[e.target.value as keyof typeof SharedAmbientSurrounding]; onChange(selected); }} > {getEnumKeys(SharedAmbientSurrounding).map((key, index) => ( <option key={index} value={SharedAmbientSurrounding[key]}> {key} </option> ))} </select> ); }
原理说明
React遵循单向数据流,子组件的内部状态父组件无法直接访问。通过把状态提升到共同的父组件,子组件仅负责渲染和触发状态更新,父组件统一管理所有表单字段的状态,就能在提交时获取到所有字段的值。
内容的提问来源于stack exchange,提问作者Ismail Yaman
相关产品推荐
相关产品推荐

