Tengo el siguiente código simple y estoy tratando de reescribirlo como una función para evitar clases y usar ganchos con fines de aprendizaje. Como puede ver a continuación, ‘Aplicación’ está extendiendo ‘Formulario’. El código completo incluye otras funciones en ‘Formulario’, por ejemplo, una función de validación que se llama por ‘handleChange’ y modifica el elemento ‘errores’ en el estado. Tenga en cuenta que ‘Formulario’ no es parte de ‘Aplicación’ porque otros componentes (como un componente de inicio de sesión) reutilizarán el formulario.

Mis preguntas principales

1- Según la documentación , parecen desalentar el uso de Herencia, ¿cómo puedo reescribir esto sin usar «extendidos» (y mantener las clases)?

2- ¿Cómo puedo reescribir esto sin clases?

Hasta ahora, la única idea que se me ocurrió es reescribir todas las funciones en form.jsx como funciones independientes y llamarlas desde la aplicación (ver más abajo). Pero esto implica escribir muchos accesorios y parámetros (especialmente cuando la validación se agrega como ‘errores’, ‘setErrors’, ‘esquema’, etc. se enviarían desde ‘App’ a ‘renderInput’, desde aquí a ‘handleChange’ , etc. Funciona pero el código está menos limpio que antes …

app.js

class App extends Form { state = { data: { username: "", password: "" }, }; render() { return ( {amp}lt;form action=""{amp}gt; {this.renderInput("username", "Username")} {this.renderInput("password", "Password", "password")} {amp}lt;/form{amp}gt; ); } } 

form.jsx

 class Form extends Component { state = { data: {}, }; handleChange = ({ currentTarget }) ={amp}gt; { const data = { ...this.state.data }; data[currentTarget.name] = currentTarget.value; this.setState({ data }); }; renderInput(name, label, type = "text") { const { data, errors } = this.state; return ( {amp}lt;Input name={name} type={type} value={data[name]} label={label} onChange={this.handleChange} /{amp}gt; ); } render() { return null; } } export default Form; 

input.jsx

 const Input = ({ name, label, ...rest }) ={amp}gt; { return ( {amp}lt;div className="form-group"{amp}gt; {amp}lt;label htmlFor={name}{amp}gt;{label}{amp}lt;/label{amp}gt; {amp}lt;input {...rest} name={name} id={name} className="form-control" /{amp}gt; {amp}lt;/div{amp}gt; ); }; 

Intente cambiarlo a funciones:

App.jsx

 const App = () ={amp}gt; { const [user, setUser] = useState({ username: "", password: "" }); return ( {amp}lt;form action=""{amp}gt; {renderInput("username", "Username", user, setUser)} {renderInput("password", "Password", user, setUser, "password")} {amp}lt;/form{amp}gt; ); }; 

form.jsx

 export function handleChange({ currentTarget }, data, setData) { setData({ ...data, [currentTarget.name]: currentTarget.value }); } export function renderInput(name, label, data, setData, type = "text") { return ( {amp}lt;Input name={name} type={type} value={data[name]} label={label} onChange={e ={amp}gt; handleChange(e, data, setData)} /{amp}gt; ); } 

Gracias de antemano y avíseme si necesita una mejor explicación o el código completo.

Mueva el form al componente Form y pase una matriz de propiedades de entradas para generar entradas:

App.jsx

 const App = () ={amp}gt; { const [user, setUser] = useState({ username: "", password: "" }); const inputList = [ {name: "username", label: "Username", value: user.username}, {name: "password", label: "Password", value: user.password, type: "password"} ] return ( {amp}lt;Form inputList={inputList} setData={setUser} /{amp}gt; ); }; 

Form.jsx

 const Form = ({ inputList, setData }) ={amp}gt; { const handleChange = ({ currentTarget }) ={amp}gt; { const { name, value } = currentTarget; setData(prevData ={amp}gt; ({ ...prevData, [name]: value })); }; return ( {amp}lt;form action=""{amp}gt; { inputList.map(({ name, label, value, type = "text" }) ={amp}gt; {amp}lt;Input key={name} name={name} type={type} value={value} label={label} onChange={handleChange} /{amp}gt; ) } {amp}lt;/form{amp}gt; ); }