Estoy tratando de crear componentes reutilizables para un formulario de dirección dinámica. Necesito agregar controladores de eventos personalizados a los componentes. Actualmente, cada campo de entrada en el formulario de dirección se crea a partir de la siguiente matriz de objetos. ¿Puedo agregar controladores de eventos personalizados a la siguiente matriz o debo considerar otro enfoque para lograrlos?
Campos de direcciones.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 AddressFormEntrada.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 InputCreo que está bien agregar sus funciones de controlador a la matriz de datos, especialmente si es solo un proyecto pequeño. Al menos parece que no es raro.
Pero si prefiere seguir más estrictamente el principio de separar datos y lógica (como hago yo), entonces no debe agregar funciones a la matriz de datos, sino solo 'algo' que identifique lo que sería válido.
Además, tenga en cuenta que si está utilizando funciones dentro de matrices de datos, la matriz de datos ya no se puede encadenar , si eso es importante para usted (por ejemplo, para pasarla por la red, los trabajadores, el almacenamiento, ...).
Si los requisitos se vuelven más complicados , un identificador para el requisito ya no puede ser una clave simple (como "isNaN" ), sino que necesitará algún tipo de 'sintaxis' personalizada, por ejemplo, "shouldBeBetween:10,99" , que necesita ser analizado
Si se vuelve muy complicado , supongo que se debe considerar permanecer con las funciones dentro de la matriz de datos en aras de la simplicidad (si no es necesario stringify), o usar una biblioteca que admita las validaciones deseadas.
(para esto necesitas conocer todos los validadores posibles de antemano)
export const AddressFields = [ { name: "FirstName", ..., validate: [ 'isNaN', // <-- some 'key' to identify the requirement ... // <-- optionally more additional requirements ] }, ];Entonces tendría alguna colección de todos los validadores posibles, por ejemplo:
const validators = { isNaN: ( data ) => isNaN( data ), // ... more additional validators };Para cada entrada, crearía y llamaría a los validadores necesarios, por ejemplo:
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> ) }