Я ищу наилучшую практику для того, чтобы компонент ReactJS отвечал за форму для пользователей, чтобы редактировать данный объект. Здесь очень упрощенный пример. Фактические формы во многих случаях имели бы еще несколько полей и больше функциональных возможностей графического интерфейса.
React.createClass({
getInitialState: function() {
return {
entity: {
property1: null,
property2: null
}
};
},
handleChange: function(e) {
var entity = this.state.entity;
switch(e.target.name) {
case 'property1':
entity.property1 = e.target.value;
break;
case 'property2':
entity.property2 = e.target.value;
break;
}
this.setState({
entity: entity
});
},
render: function() {
return (
<div className="entity-form">
<form onChange={this.handleChange}>
<input type="text" name="property1" value={this.state.entity.property1} />
<br />
<textarea name="property2" value={this.state.entity.property2}></textarea>
<br />
</form>
</div>
);
}
});
Поля формы непосредственно редактируют объект сущности, который затем можно сохранить в RESTful api. Я хочу, чтобы компонент обновлялся, когда пользователь менял поля, поэтому графический интерфейс мог реагировать на основе ввода во время ввода (например, проверки, информация и т.д.).
В теории, я мог бы, чтобы весь объект состояния представлял объект, который редактируется, поэтому каждое свойство объекта является переменными состояния первого уровня. Тем не менее, я хочу иметь возможность добавлять дополнительные переменные состояния для функций GUI и другие вещи, связанные с тем, что будет делать компонент, поэтому я предпочел бы, чтобы объект объекта был одной переменной состояния, такой как переменная состояния "entity" выше. Конечно, объект может быть более сложным объектом, например, моделью Backbone или аналогичной, но в этом упрощенном примере я просто использую простой объект с требуемыми свойствами.
Итак, в поисках наилучшего способа сделать компоненты React для этой цели, у меня есть несколько вопросов:
- Реквизит или состояние.
В этом случае я решил поместить объект entity с содержимым для формы в переменную состояния вместо prop. Это позволяет обновлять объект во время ввода формы без вызова родителя и обновления реквизита. Что касается моего опыта React, это будет лучшей практикой для компонента формы, подобного этому.
- Управляемые или неконтролируемые входы.
В упрощенном примере выше я использую управляемые входы. Это приводит к обновлению состояния и повторному рендерингу компонента при каждом изменении (как и каждый символ, введенный в текстовое поле). Это лучшая практика? Хорошо, что компонент имеет полный контроль над тем, что происходит, вместо параметров defaultValue и на каком-либо событии (например, нажатии кнопки сохранения пользователем) компонент извлекает значения, обновляет объект и сохраняет его на сервере. Существуют ли какие-либо причины (или мнения), если в таких случаях следует использовать контролируемые или неконтролируемые входы?
- onChange для формы или каждого входа
В примере есть onChange в теге формы, и он вызывает метод handleChange каждый раз, когда изменяется любое из полей в форме. Однако, поскольку входы управляются (имеют значения параметров), React жалуется, что поля ввода не имеют свойства onChange. Означает ли это, что общий критерий onChange в теге формы является плохой практикой, и я должен удалить его и вместо этого поставить onChange на каждое отдельное поле?
- Обновление отдельных свойств
В приведенном выше примере я использую коммутатор на основе того, какое поле ввода обновляется (когда вызывается handleChange). Наверное, я мог бы вместо этого убедиться, что все имена полей синхронизированы с именами свойств объекта, и я могу установить свойства объекта entity в handleChange на основе имени поля из события (e.target.name). Однако это затрудняет индивидуальные потребности в поле, даже если большинство полей просто обновляют свойство объекта напрямую. Я предполагаю, что alternativ - это переключатель с настройкой по умолчанию на основе имени ввода и блоки case для любого поля, для которого требуются другие способы обновления (например, фильтрация значения перед установкой его на объект). Пожалуйста, прокомментируйте это, если вы знаете, что гораздо лучший способ обработки полевых обновлений таким образом.
- Обновление объекта состояния
Одной большой проблемой этого примера является способ обновления объекта сущности. Поскольку переменная entity в handleChange задана объектом сущности из текущего состояния, это всего лишь указатель, и обновление переменной сущности изменяет объект в состоянии. На страницах React говорится, что вы никогда не должны обновлять состояние напрямую. Одна из причин - это то, что я испытал при обновлении состояния до вызова setState. Если у вас есть метод mustComponentUpdate, prevState содержит новое состояние, поскольку содержимое аргумента prevState, отправленного в файл shouldComponentUpdate, основывается на том, что было в состоянии при вызове setState. Насколько я знаю, нет простого способа клонировать объект в javascript. Поэтому возникает вопрос, когда у меня есть целые объекты, которые мне нужно обновлять свойства (и не касаться других значений в объекте), а не просто запускать setState одной переменной состояния, что лучший способ сделать это, не вызывая эти виды смешанных состояний?