React+TypeScript:如何创建TextFieldProps实例实现动态文本框容器?
解决方案
首先修正MyTextField组件,适配MUI的onChange事件参数格式,提取输入值后再传递给setValue:
import { TextField, ChangeEvent } from '@mui/material'; interface TextFieldProps { value: string; setValue: (newValue: string) => void; } function MyTextField(props: TextFieldProps) { const handleChange = (e: ChangeEvent<HTMLInputElement>) => { props.setValue(e.target.value); }; return <TextField value={props.value} onChange={handleChange} />; }
接下来重构容器组件,通过维护值数组统一管理所有文本框状态,无需直接存储TextFieldProps实例:
import { useState } from 'react'; import { Button } from '@mui/material'; function Container() { // 用字符串数组存储所有文本框的值,初始包含一个空字符串对应默认显示的文本框 const [textValues, setTextValues] = useState<string[]>(['']); // 添加新文本框:向数组末尾追加空字符串 const addTextField = () => { setTextValues(prev => [...prev, '']); }; // 更新指定索引的文本框值 const updateTextFieldValue = (index: number, newValue: string) => { setTextValues(prev => { const newValues = [...prev]; newValues[index] = newValue; return newValues; }); }; return ( <> {/* 渲染所有文本框 */} {textValues.map((value, index) => ( <MyTextField key={index} value={value} setValue={(newValue) => updateTextFieldValue(index, newValue)} /> ))} {/* 添加文本框按钮 */} <Button onClick={addTextField} variant="contained" style={{ marginTop: 16 }}> 添加文本框 </Button> </> ); }
关键说明
- 容器通过
textValues数组直接获取所有文本框的值,无需额外存储setter函数。 - 每个文本框的
setValue是绑定了对应索引的闭包函数,调用时会精准更新数组中对应位置的值。 - 初始状态设为
[''],确保页面加载时默认显示一个空文本框。
如果需要支持删除文本框,可添加如下逻辑:
// 在Container组件中添加删除方法 const removeTextField = (index: number) => { setTextValues(prev => prev.filter((_, i) => i !== index)); }; // 修改渲染逻辑,为每个文本框添加删除按钮 {textValues.map((value, index) => ( <div key={index} style={{ display: 'flex', gap: 8, marginBottom: 8 }}> <MyTextField value={value} setValue={(newValue) => updateTextFieldValue(index, newValue)} /> <Button onClick={() => removeTextField(index)} variant="outlined" color="error"> 删除 </Button> </div> ))}
内容的提问来源于stack exchange,提问作者MakePeaceGreatAgain
相关产品推荐
相关产品推荐

