如何在React表单中获取自定义输入组件的内部input值?
解决React TypeScript自定义表单组件无法被form获取值的问题
你可以通过以下两种方案实现表单提交时直接获取自定义组件内部<input>的值,无需实时同步状态:
方案1:通过useImperativeHandle暴露内部值
让自定义组件对外暴露获取值的方法,父组件在提交时调用该方法即可。
修改SmartInput组件
使用forwardRef和useImperativeHandle让组件支持ref,并暴露获取值的接口:
import React, { forwardRef, useImperativeHandle, useState } from 'react'; export interface SmartInputProps { items: any[]; itemKey: string; // 透传原生input的其他属性(可选) [key: string]: any; } // 定义组件对外暴露的方法 interface SmartInputHandle { getValue: () => string; } export const SmartInput = forwardRef<SmartInputHandle, SmartInputProps>( ({ items, itemKey = 'name', ...rest }, ref) => { const [inputValue, setInputValue] = useState(''); // 暴露getValue方法给父组件 useImperativeHandle(ref, () => ({ getValue: () => inputValue, })); const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { setInputValue(e.target.value); // 这里保留你的模糊搜索逻辑 }; return ( <div> <input value={inputValue} onChange={handleInputChange} {...rest} // 透传name、placeholder等原生属性 /> {/* 模糊搜索结果列表 */} </div> ); } );
在父组件中使用
创建ref并在提交时调用getValue:
import React, { useRef } from 'react'; import { SmartInput, SmartInputHandle } from './SmartInput'; export const SearchBar: React.FC = () => { const smartInputRef = useRef<SmartInputHandle>(null); const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); const inputValue = smartInputRef.current?.getValue(); console.log('提交的输入值:', inputValue); // 后续处理逻辑 }; return ( <div className="searchbar-wrapper"> <form onSubmit={handleSubmit}> <SmartInput ref={smartInputRef} items={options} itemKey="name" name="search-input" // 可选,方便其他场景使用 /> <input type="submit" value="OK" /> </form> </div> ); };
方案2:利用原生FormData获取值
让自定义组件透传原生input的name属性,并确保内部input的值与组件状态同步,提交时直接通过FormData读取值。
修改SmartInput组件
import React, { useState } from 'react'; export interface SmartInputProps { items: any[]; itemKey: string; name?: string; placeholder?: string; // 其他自定义属性 } export const SmartInput: React.FC<SmartInputProps> = ({ items, itemKey = 'name', name, placeholder, }) => { const [inputValue, setInputValue] = useState(''); const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { setInputValue(e.target.value); // 模糊搜索逻辑 }; return ( <div> <input value={inputValue} onChange={handleInputChange} name={name} // 必须设置name,FormData通过name取值 placeholder={placeholder} /> {/* 模糊搜索结果列表 */} </div> ); };
在父组件中获取值
提交时通过FormData读取:
import React from 'react'; import { SmartInput } from './SmartInput'; export const SearchBar: React.FC = () => { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); const formData = new FormData(e.currentTarget); const inputValue = formData.get('search-input') as string; console.log('提交的输入值:', inputValue); // 后续处理逻辑 }; return ( <div className="searchbar-wrapper"> <form onSubmit={handleSubmit}> <SmartInput items={options} itemKey="name" name="search-input" // 对应FormData的key /> <input type="submit" value="OK" /> </form> </div> ); };
方案对比
- 方案2更贴合原生表单行为,无需额外维护ref,适合大多数场景;
- 方案1更灵活,除了获取值还可以暴露其他方法(比如
focus),适合需要更多组件交互的场景; - 两种方案都不需要父组件实时处理
onChange事件,仅在表单提交时获取值,符合你的需求。
内容的提问来源于stack exchange,提问作者fraxton
相关产品推荐
相关产品推荐

