React Suite中带验证的Form内Textarea输入异常问题
解决React Suite Form.Control包裹文本域仅能输入单个字符的问题
你在使用React Suite构建带表单验证的文本域页面时,遇到了通过Form.Control包裹的文本域每次仅能输入一个字符的异常,而直接使用Input as="textarea"则正常。
问题原因
核心矛盾在于自定义TextArea组件与Form.Control的事件传递逻辑不匹配:
- React Suite的
Input组件(当as="textarea"时)的onChange接收的是事件对象; - 但
Form.Control传递给accepter的onChange期望直接接收输入值本身。
两者参数类型不匹配,导致表单值更新异常,出现输入卡顿。
解决方案
方案1:直接使用Input作为accepter(推荐)
不需要自定义组件,直接将Input作为Form.Control的accepter,并传递as="textarea"属性即可:
import React from "react"; import ReactDOM from "react-dom"; import { Input, Form, Schema } from "rsuite"; const App = () => { const [formValue, setFormValue] = React.useState({ desc: "" }); const model = Schema.Model({ desc: Schema.Types.StringType().isRequired("required"), }); const formRef = React.useRef(); return ( <> <Form model={model} formValue={formValue} onChange={setFormValue} ref={formRef} > <Input as="textarea" rows={3} placeholder="Textarea1" /> {/* 直接使用Input作为accepter,传递as="textarea" */} <Form.Control name="desc" placeholder="Form textarea" rows={3} accepter={Input} as="textarea" /> </Form> </> ); }; ReactDOM.render(<App />, document.getElementById("root"));
方案2:修复自定义TextArea组件的事件传递
如果必须自定义组件,需要在组件内部转换onChange的参数类型,将Input的事件对象转换为值后再传递给Form.Control的onChange:
import React from "react"; import ReactDOM from "react-dom"; import { Input, Form, Schema } from "rsuite"; const App = () => { const [formValue, setFormValue] = React.useState({ desc: "" }); const model = Schema.Model({ desc: Schema.Types.StringType().isRequired("required"), }); // 修复自定义组件的onChange事件,转换参数类型 const TextArea = React.forwardRef(({ onChange, ...props }, ref) => { const handleChange = (e) => { // 将Input的事件对象转换为值,传递给Form.Control的onChange onChange?.(e.target.value); }; return <Input {...props} as="textarea" ref={ref} onChange={handleChange} />; }); const formRef = React.useRef(); return ( <> <Form model={model} formValue={formValue} onChange={setFormValue} ref={formRef} > <Input as="textarea" rows={3} placeholder="Textarea1" /> <Form.Control name="desc" placeholder="Form textarea" accepter={TextArea} /> </Form> </> ); }; ReactDOM.render(<App />, document.getElementById("root"));
内容的提问来源于stack exchange,提问作者Andry
相关产品推荐
相关产品推荐

