У меня есть следующий простой код, и я пытаюсь переписать его как функцию, избегая классов и используя хуки для целей обучения. Как вы можете видеть ниже, «приложение» расширяет «форму». Полный код включает в себя другие функции в «Form», например, функцию проверки, которая вызывается методом handleChange и изменяет элемент «ошибки» в состоянии. Обратите внимание, что «Форма» не является частью «Приложения», потому что Форма будет использоваться другими компонентами (такими как компонент входа в систему).

Мои основные вопросы:

1- Согласно документации , они, кажется, препятствуют использованию Наследования, как я могу переписать это, не используя «extends» (и сохраняя классы)?

2- Как я могу переписать это без классов?

Пока что единственная идея, которая пришла мне в голову, — переписать все функции в form.jsx как независимые функции и вызвать их из App (см. Ниже). Но это подразумевает написание большого количества реквизитов и параметров (особенно, когда проверка добавляется как «ошибки», «setErrors», «схема» и т. Д. Будут отправлены из «App» в «renderInput», отсюда в «handleChange») и т.д. Это работает, но код менее чистый, чем раньше …

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; ); }; 

Попытайтесь изменить его на функции:

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; ); } 

Спасибо заранее и дайте мне знать, если вам нужно лучшее объяснение или полный код.

Переместите form в компонент Form и передайте массив свойств входных данных, чтобы сгенерировать входные данные:

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; ); }