Я ищу элегантный способ структурировать свой большой компонент формы. - Мой код выглядит примерно так, как показано ниже.
Мне нелегко читать, и хотя я знаю, что этот вопрос субъективен тому, как человек предпочитает работать, я хотел бы знать, как бы я разбил этот компонент, чтобы сделать его более разборчивым.
В идеале я хочу разделить функции внутри этого отдельного компонента на отдельные компоненты. Я использую грубый пример из одного из моих собственных проектов, чтобы я мог лучше понять лучшие практики для этого типа рефакторинга.
Как вы можете видеть, форма onSubmit запрограммирована для визуализации кода, а также для загрузки код. Форма принимает состояние из нескольких входов и предназначена для создания обновленного файла HTML, который возвращается с помощью функции Result.
Теперь это не рабочий код, а грубый пример для всех функции, участвующие в моем компоненте. - Фрагмент не будет запущен, потому что ReactDomServer вызывается для загрузки вывода в виде файла HTML с использованием renderToStaticMarkup, и он недоступен во фрагменте.
Заранее благодарен за любую помощь в упрощении.
function Result(props) {
const { image, title, bodyText, btnText, btnUrl, btnColor } = props;
return <div dangerouslySetInnerHTML={{
__html: `
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div>
<tbody>
<tr>
<td style="vertical-align:top;padding:0px;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="" width="100%">
<tr>
<td align="center" style="font-size:0px;padding:0px;word-break:break-word;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:collapse;border-spacing:0px;">
<tbody>
<tr>
<td style="width:600px;"> <img alt="" height="auto" src="" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;"
width="600"> </td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>`}</div>;
}
function download(filename, text) {
let element = document.createElement('a');
element.setAttribute(
'href',
'data:text/plain;charset=utf-8,' + encodeURIComponent(text)
);
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
function BasicHtml(props) {
const { title, children } = props;
return (
<html>
<head>
<title>{title}</title>
</head>
<body>{children}</body>
</html>
);
}
export default class FormComponent extends React.Component {
state = { name: '', age: null, submitted: false };
handleChange = e => {
this.setState({ [e.target.name]: e.target.value });
};
handleSubmit = e => {
e.preventDefault();
this.setState({ submitted: true });
this.generateHtmlFile();
};
generateHtmlFile = () => {
const { name, age } = this.state;
const formHtml = ReactDomServer.renderToStaticMarkup(
<BasicHtml title={name}>
<FormComponent />
</BasicHtml>
);
const resultHtml = ReactDomServer.renderToStaticMarkup(
<BasicHtml title={name}>
<Result name={name} age={age} />
</BasicHtml>
);
download('result.html', resultHtml);
download('form.html', formHtml);
};
render() {
const { name, age, submitted } = this.state;
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
Name:{' '}
<input
name="name"
type="text"
value={this.state.name}
onChange={this.handleChange}
required
/>
</label>
<br />
<br />
<label>
Age:{' '}
<input
name="age"
type="number"
value={this.state.age}
onChange={this.handleChange}
required
/>
</label>
<br />
<br />
<input type="submit" value="Submit" />
</form>
<br />
{submitted ? <Result name={name} age={age} /> : null}
</div>
);
}
}
ReactDOM.render(<FormComponent />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>