Javascript 对组件中的输入处理程序进行重复反应
我有一个react组件,看起来像下面给出的 表单输入使用Javascript 对组件中的输入处理程序进行重复反应,javascript,reactjs,Javascript,Reactjs,我有一个react组件,看起来像下面给出的 表单输入使用onInputChange功能处理,表单提交由onFormSubmit function RegisterForm() { // formData stores all the register form inputs. const [formData, setFormData] = useState(registerDefault); const [errors, posting, postData] = useDataPos
onInputChange
功能处理,表单提交由onFormSubmit
function RegisterForm() {
// formData stores all the register form inputs.
const [formData, setFormData] = useState(registerDefault);
const [errors, posting, postData] = useDataPoster();
function onInputChange(event: ChangeEvent<HTMLInputElement>) {
let update = { [event.target.name]: event.target.value };
setFormData(oldForm => Object.assign(oldForm, update));
}
function onFormSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const onSuccess: AxiosResponseHandler = response => {
setFormData(Object.assign(formData, response.data));
};
postData("/api/register", formData, onSuccess);
}
return (
<form onSubmit={onFormSubmit}>
<FormTextInput
name="full_name"
label="Name"
errors={errors.full_name}
onChange={onInputChange}
/>
<FormTextInput
name="email"
label="Email address"
type="email"
errors={errors.email}
onChange={onInputChange}
/>
<button type="submit" className="theme-btn submit" disabled={posting}>
{posting && <span className="fas fa-spin fa-circle-notch"></span>}
Create
</button>
</form>
);
}
函数寄存器执行(){
//formData存储所有注册表表单输入。
const[formData,setFormData]=使用状态(registerDefault);
const[errors,posting,postData]=useDataPoster();
函数onInputChange(事件:ChangeEvent){
让update={[event.target.name]:event.target.value};
setFormData(oldForm=>Object.assign(oldForm,update));
}
函数onFormSubmit(事件:FormEvent){
event.preventDefault();
const onSuccess:AxiosResponseHandler=response=>{
setFormData(Object.assign(formData,response.data));
};
postData(“/api/register”,formData,onSuccess);
}
返回(
{发布&&}
创造
);
}
我的应用程序有50多个类似的表单,我想知道我是否必须在所有其他表单上复制粘贴这两个功能onInputChange
不会有任何变化,url是onFormSubmit
中唯一的变量
我正在考虑一种基于类的方法,将setFormData
和postData
作为属性,将所讨论的函数作为类方法。但是在这种情况下,我必须将处理程序与类实例绑定,以便处理程序具有有效的这个实例
还有别的办法吗?如何避免在所有表单组件中重复这两个代码块
谢谢创建一个HOC将输入处理程序注入表单组件,并为url
添加参数
function RegisterForm(props) {
// specific function
const specific = () => {
const formData = props.formData; // use passed state values
// use form data
}
}
function withInputHandlers(Component, params) {
return function(props) {
// states
function onInputChange(...) {...}
function onFormSubmit(...) {
// use params.url when submitting
postData(params.url, formData, onSuccess);
}
// inject input handlers to component and state values
return (
<Component {...props} formData={formData} onChange={onInputChange} onSubmit={onFormSubmit} />
);
}
}
// Usage
const EnhancedRegisterForm = withInputHandlers(
RegisterForm,
{ url: 'register_url' } // params
);
const EnhancedSurveyForm = withInputHandlers(
Survey,
{ url: 'survey_url' } // params
)
功能注册表执行(道具){
//特定功能
常量特定=()=>{
const formData=props.formData;//使用传递的状态值
//使用表单数据
}
}
具有InAuthHandler的函数(组件、参数){
返回功能(道具){
//州
函数onInputChange(…){…}
函数onFormSubmit(…){
//提交时使用params.url
postData(params.url、formData、onSuccess);
}
//将输入处理程序注入组件和状态值
返回(
);
}
}
//用法
const EnhancedRegisterForm=带有权限句柄(
注册执行,
{url:'register_url'}//params
);
const EnhancedSurveyForm=带有权限句柄(
调查
{url:'survey_url'}//params
)
您可以创建一个自定义挂钩,如下所示:
const[formState,setFormState]=useFormStateHandler({name:'})
setFormState(事件“名称”)}/>
定义如下所示:
导出默认函数useFormStateHandler(initialState){
常量[状态,设置状态]=使用状态(初始状态)
常量更新程序=(事件,名称)=>{
setState({…状态,[名称]:event.target.value})
}
返回[状态,更新程序]
}
此更改可能会对您有所帮助
function RegisterForm() {
// formData stores all the register form inputs.
const [formData, setFormData] = useState(registerDefault);
const [errors, posting, postData] = useDataPoster();
const onInputChange = name => event => {
let update = { [name]: event.target.value };
setFormData(oldForm => Object.assign(oldForm, update));
}
const onFormSubmit = url => event =>{
event.preventDefault();
const onSuccess: AxiosResponseHandler = response => {
setFormData(Object.assign(formData, response.data));
};
postData(url, formData, onSuccess);
}
return (
<form onSubmit={onFormSubmit("/api/register")}>
<FormTextInput
name="full_name"
label="Name"
errors={errors.full_name}
onChange={onInputChange("full_name")}
/>
<FormTextInput
name="email"
label="Email address"
type="email"
errors={errors.email}
onChange={onInputChange("email")}
/>
<button type="submit" className="theme-btn submit" disabled={posting}>
{posting && <span className="fas fa-spin fa-circle-notch"></span>}
Create
</button>
</form>
);
}
函数寄存器执行(){
//formData存储所有注册表表单输入。
const[formData,setFormData]=使用状态(registerDefault);
const[errors,posting,postData]=useDataPoster();
const onInputChange=name=>event=>{
让update={[name]:event.target.value};
setFormData(oldForm=>Object.assign(oldForm,update));
}
const onFormSubmit=url=>event=>{
event.preventDefault();
const onSuccess:AxiosResponseHandler=response=>{
setFormData(Object.assign(formData,response.data));
};
postData(url、formData、onSuccess);
}
返回(
{发布&&}
创造
);
}
我喜欢这种方法。但这一外观因更新而关闭。如果有其他特定于组件的功能需要访问状态,该怎么办?@KaleshKaladharan,您也可以将状态注入组件。对于特定于组件的其他功能,它将仅位于组件本身内部。我已经更新了代码,显示了这样的问题。我想你不明白我的问题。我试图用多个组件共享onInputChange
和onFormSubmit
代码。这看起来不错。如果我还返回设置状态
,那么我将能够直接更改组件中的状态(如果需要)。我在等待所有可能的选择。你还有其他解决办法吗?你觉得我提到的基于类的方法怎么样。这有什么缺点吗?无论是基于类的HOC还是像这样的自定义钩子都做同样的工作,我只是更喜欢在钩子中编写,因为它问世了,是的,你需要一些自定义状态更新时,setState
也可以传递。这个答案完全是根据个人喜好选择的。创建自定义钩子看起来更干净,尤其是当我的应用程序已经尽可能使用钩子时。