如何在从对象数组创建的可重用 React 组件中添加事件处理程序
How Can i Add Event Handlers In Reusable React Component Created from Object Array
我正在尝试为动态地址表单创建可重复使用的组件。我需要向组件添加自定义事件处理程序。目前,Address 表单中的每个输入字段都是从以下对象数组创建的,我可以将自定义事件处理程序添加到以下数组吗,或者我是否需要考虑另一种方法来实现这些。
AddressFields.js
export const AddressFields =[
{name:"FirstName", type:"text", title:"First Name", id:"AddressFirst" ,validate:(data)=>isNaN(data)},
{name:"LastName", type:"text", title:"Last Name", id:"AddressLast",validate:(data)=>isNaN(data)},
{name:"AddressLine1", type:"text", title:"Address Line 1", id:"Address1",validate:(data)=>isNaN(data)},
{name:"AddressLine2", type:"text", title:"Address Line 2", id:"Address2",validate:(data)=>isNaN(data)},
{name:"City", type:"text", title:"City", id:"AddressCity",validate:(data)=>isNaN(data)},
{name:"Pin", type:"number", title:"Pin Code", id:"AddressPin",validate:(data)=>isNaN(data)},
{name:"State", type:"text", title:"State", id:"AddressState",validate:(data)=>isNaN(data)},
{name:"Phone", type:"number", title:"Phone ", id:"AddressPhone",validate:(data)=>isNaN(data)},
{name:"Email", type:"email", title:"Email ", id:"AddressEmail",validate:(data)=>isNaN(data)},];
AddressForm.js
import Input from "../UI/Input"
import { AddressFields } from "./AddressFields"
const AddressForm = () => {
return (
<div id="ShippingAddress" className="">
{AddressFields.map((addr)=>{
return <Input name={addr.name} id={addr.id} title={addr.title} type={addr.type}/>
})}
</div>
)
}
export default AddressForm
Input.js
import { useState } from "react";
const Input = (props) => {
const [isValid,setIsValid]=useState(true);
return (
<div>
<label for={props.name}>{props.title}</label>
<input id={props.id} name={props.name} type={props.type} onBlur={isValid=props.validate()} />
</div>
)
}
export default Input
我认为有点可以将您的处理函数添加到数据数组,
特别是如果它只是一个小项目。至少看起来并不少见。
但是如果你更喜欢更严格遵循分离数据和逻辑的原则(就像我一样),
那么你不应该向数据数组添加函数,而只是 'something' 标识什么是有效的。
另外请注意,如果您在数据数组内部使用函数,则数据数组不能
stringified 如果这对您很重要(例如通过网络、工作人员、存储等传递它)。
如果需求变得更复杂,需求的标识符不能再是简单的键(如"isNaN"
),
但您需要某种自定义 'syntax',例如"shouldBeBetween:10,99"
,需要解析
如果它变得非常复杂我想应该考虑保留
数据数组为了简单起见(如果不需要 stringify),或者使用支持所需验证的库。
分离数据和逻辑的示例
(为此你需要提前知道所有可能的验证器)
export const AddressFields = [
{
name: "FirstName",
...,
validate: [
'isNaN', // <-- some 'key' to identify the requirement
... // <-- optionally more additional requirements
]
},
];
然后你会得到所有可能的验证器的集合,例如:
const validators = {
isNaN: ( data ) => isNaN( data ),
// ... more additional validators
};
对于每个输入,您将创建并调用所需的验证器,例如:
const createValidator = function( validatorKeys ){
return function( data ){
return validatorKeys.every( key => {
const currentValidator = validators.hasOwnProperty( key ) && validators[ key ];
return currentValidator && currentValidator( data );
})
}
}
const Input = (props) => {
const [ isValid, setIsValid ] = useState( true );
const [ value, setValue ] = useState();
const validatorForThisItem = createValidator( props.validate );
return (
<div>
<label for={ props.name }>{ props.title }</label>
<input id={ props.id } name={ props.name } type={ props.type } onBlur={ () => {
setIsValid( validatorForThisItem( value ) );
}} />
</div>
)
}
我正在尝试为动态地址表单创建可重复使用的组件。我需要向组件添加自定义事件处理程序。目前,Address 表单中的每个输入字段都是从以下对象数组创建的,我可以将自定义事件处理程序添加到以下数组吗,或者我是否需要考虑另一种方法来实现这些。
AddressFields.js
export const AddressFields =[
{name:"FirstName", type:"text", title:"First Name", id:"AddressFirst" ,validate:(data)=>isNaN(data)},
{name:"LastName", type:"text", title:"Last Name", id:"AddressLast",validate:(data)=>isNaN(data)},
{name:"AddressLine1", type:"text", title:"Address Line 1", id:"Address1",validate:(data)=>isNaN(data)},
{name:"AddressLine2", type:"text", title:"Address Line 2", id:"Address2",validate:(data)=>isNaN(data)},
{name:"City", type:"text", title:"City", id:"AddressCity",validate:(data)=>isNaN(data)},
{name:"Pin", type:"number", title:"Pin Code", id:"AddressPin",validate:(data)=>isNaN(data)},
{name:"State", type:"text", title:"State", id:"AddressState",validate:(data)=>isNaN(data)},
{name:"Phone", type:"number", title:"Phone ", id:"AddressPhone",validate:(data)=>isNaN(data)},
{name:"Email", type:"email", title:"Email ", id:"AddressEmail",validate:(data)=>isNaN(data)},];
AddressForm.js
import Input from "../UI/Input"
import { AddressFields } from "./AddressFields"
const AddressForm = () => {
return (
<div id="ShippingAddress" className="">
{AddressFields.map((addr)=>{
return <Input name={addr.name} id={addr.id} title={addr.title} type={addr.type}/>
})}
</div>
)
}
export default AddressForm
Input.js
import { useState } from "react";
const Input = (props) => {
const [isValid,setIsValid]=useState(true);
return (
<div>
<label for={props.name}>{props.title}</label>
<input id={props.id} name={props.name} type={props.type} onBlur={isValid=props.validate()} />
</div>
)
}
export default Input
我认为有点可以将您的处理函数添加到数据数组, 特别是如果它只是一个小项目。至少看起来并不少见。
但是如果你更喜欢更严格遵循分离数据和逻辑的原则(就像我一样), 那么你不应该向数据数组添加函数,而只是 'something' 标识什么是有效的。
另外请注意,如果您在数据数组内部使用函数,则数据数组不能 stringified 如果这对您很重要(例如通过网络、工作人员、存储等传递它)。
如果需求变得更复杂,需求的标识符不能再是简单的键(如"isNaN"
),
但您需要某种自定义 'syntax',例如"shouldBeBetween:10,99"
,需要解析
如果它变得非常复杂我想应该考虑保留 数据数组为了简单起见(如果不需要 stringify),或者使用支持所需验证的库。
分离数据和逻辑的示例
(为此你需要提前知道所有可能的验证器)
export const AddressFields = [
{
name: "FirstName",
...,
validate: [
'isNaN', // <-- some 'key' to identify the requirement
... // <-- optionally more additional requirements
]
},
];
然后你会得到所有可能的验证器的集合,例如:
const validators = {
isNaN: ( data ) => isNaN( data ),
// ... more additional validators
};
对于每个输入,您将创建并调用所需的验证器,例如:
const createValidator = function( validatorKeys ){
return function( data ){
return validatorKeys.every( key => {
const currentValidator = validators.hasOwnProperty( key ) && validators[ key ];
return currentValidator && currentValidator( data );
})
}
}
const Input = (props) => {
const [ isValid, setIsValid ] = useState( true );
const [ value, setValue ] = useState();
const validatorForThisItem = createValidator( props.validate );
return (
<div>
<label for={ props.name }>{ props.title }</label>
<input id={ props.id } name={ props.name } type={ props.type } onBlur={ () => {
setIsValid( validatorForThisItem( value ) );
}} />
</div>
)
}