Mithril — минималистичный и высокопроизводительный JavaScript-фреймворк для построения одностраничных приложений (SPA). Одной из ключевых особенностей при работе с формами и интерактивными элементами является различие между контролируемыми и неконтролируемыми элементами. Понимание этой концепции позволяет эффективно управлять состоянием UI и синхронизацией данных.
Контролируемым элементом считается тот элемент формы, значение
которого полностью управляется состоянием приложения. В Mithril это
достигается через привязку значения к свойству объекта и использование
события oninput или onchange для синхронизации
с состоянием.
Пример контролируемого текстового поля:
import m from "mithril";
const App = {
state: {
name: ""
},
view: () => m("div", [
m("input[type=text]", {
value: App.state.name,
oninput: e => App.state.name = e.target.value
}),
m("p", `Введённое имя: ${App.state.name}`)
])
};
m.mount(document.body, App);
Ключевые моменты:
value задаётся из состояния.Преимущество контролируемых элементов заключается в централизованном управлении данными, что облегчает валидацию, обработку и тестирование. Недостатком может быть небольшое снижение производительности при больших формах с многочисленными обновлениями, поскольку каждое изменение триггерит ререндер.
Неконтролируемый элемент управляет своим собственным состоянием, а
фреймворк лишь считывает его при необходимости. В Mithril это
достигается через работу с DOM-элементами напрямую, чаще всего через
атрибут onchange или доступ к ref.
Пример неконтролируемого текстового поля:
import m from "mithril";
const App = {
nameInput: null,
view: () => m("div", [
m("input[type=text]", {
oncreate: vnode => App.nameInput = vnode.dom
}),
m("button", {
onclick: () => alert(`Введённое имя: ${App.nameInput.value}`)
}, "Показать имя")
])
};
m.mount(document.body, App);
Ключевые моменты:
ref
(oncreate или onupdate) или
document.querySelector.Недостаток неконтролируемых элементов — сложность управления состоянием и ограниченная возможность интеграции с другими частями приложения.
| Параметр | Контролируемые элементы | Неконтролируемые элементы |
|---|---|---|
| Хранение значения | В состоянии приложения | В DOM-элементе |
| Синхронизация | Постоянная, через обработчики событий | Только при необходимости |
| Валидация данных | Легко встроить | Сложнее реализовать |
| Производительность | Немного ниже при больших формах | Выше, так как не требуется ререндер |
| Удобство тестирования | Высокое | Ограниченное |
Выбор зависит от конкретной задачи. Контролируемые элементы лучше подходят для сложных интерфейсов с частой обработкой данных, а неконтролируемые — для простых форм и полей, где достаточно одноразового считывания значения.
В Mithril контролируемые элементы позволяют строить динамическую валидацию и связывать её с состоянием:
import m from "mithril";
const App = {
state: { email: "", error: "" },
validate: () => {
App.state.error = App.state.email.includes("@") ? "" : "Неверный email";
},
view: () => m("div", [
m("input[type=email]", {
value: App.state.email,
oninput: e => {
App.state.email = e.target.value;
App.validate();
}
}),
App.state.error && m("p.error", App.state.error)
])
};
m.mount(document.body, App);
Такое использование делает интерфейс предсказуемым и управляемым, что особенно важно в масштабных приложениях.
Контролируемые элементы:
Неконтролируемые элементы:
Контролируемые и неконтролируемые элементы в Mithril обеспечивают гибкость управления формами и интерактивными компонентами. Понимание различий позволяет строить производительные и удобные интерфейсы, правильно распределяя логику между состоянием приложения и DOM.