Я начинаю с React.js и хочу создать простую форму, но в документации я нашел два способа сделать это.
Первый из них использует Refs :
var CommentForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var author = React.findDOMNode(this.refs.author).value.trim();
var text = React.findDOMNode(this.refs.text).value.trim();
if (!text || !author) {
return;
}
// TODO: send request to the server
React.findDOMNode(this.refs.author).value = '';
React.findDOMNode(this.refs.text).value = '';
return;
},
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input type="submit" value="Post" />
</form>
);
}
});
А второй использует состояние внутри компонента React:
var TodoTextInput = React.createClass({
getInitialState: function() {
return {
value: this.props.value || ''
};
},
render: function() /*object*/ {
return (
<input className={this.props.className}
id={this.props.id}
placeholder={this.props.placeholder}
onBlur={this._save}
value={this.state.value}
/>
);
},
_save: function() {
this.props.onSave(this.state.value);
this.setState({value: ''
});
});
Я не вижу плюсов и минусов двух альтернатив, если таковые существуют. Спасибо.
Ответы:
Краткая версия: избегайте ссылок.
Они плохо подходят для обслуживания и во многом теряют простоту, которую обеспечивает визуализация модели WYSIWYG.
У вас есть форма. Вам нужно добавить кнопку, которая сбрасывает форму.
У вас есть поле номера CCV во входных данных и некоторые другие поля в вашем приложении, которые являются числами. Теперь вам нужно заставить пользователя вводить только цифры.
Эх, неважно, премьер-министр хочет, чтобы мы просто сделали красный прямоугольник, если он недействителен.
Нам нужно вернуть контроль родителю. Данные теперь в реквизитах, и нам нужно реагировать на изменения.
sed -e 's/this.state/this.props/' 's/handleChange/onChange/' -i form.js
Люди думают, что refs «проще», чем держать его в состоянии. Это может быть правдой в течение первых 20 минут, но по моему опыту после этого это не так. Дайте себе возможность сказать: «Да, я сделаю это за 5 минут», а не «Конечно, я просто перепишу несколько компонентов».
источник
React.findDOMNode(this.refs.foo)
. Если вы, например, измените,this.refs.foo.props.bar
ничего не произойдет.<input onChange={this.handleChange} value={this.state.foo} />
изменили его на<input onChange={this.props.handleChange} value={this.props.foo} />
или изменили функцию (-ы) handleChange для вызова обратного (-ых) обратного вызова (-ов) в props. В любом случае, это несколько небольших очевидных изменений.input
поле, каждое из которого поддерживает свое состояние, является идеальным. В какой-то момент нам действительно нужно согласовать эти различные независимые состояния с какой-то более крупной моделью. Может быть, у нас есть автосохранение на таймере, или мы просто экономим наcomponentWillUnmount
этом, я считаюrefs
идеальным, во время согласования мы извлекаемstate
значение из каждогоref
, и никто не станет мудрее. Я согласен, что в большинстве случаевstate
это ответ, но при большом количествеinputs
использование правильногоrefs
шаблона является преимуществом для производительностиЯ видел, как несколько людей цитировали приведенный выше ответ как причину «никогда не использовать ссылки», и я хочу высказать свое (как и несколько других разработчиков React, с которыми я разговаривал) мнение.
Утверждение «не использовать ссылки» является правильным, когда речь идет об их использовании для экземпляров компонентов. Это означает, что вы не должны использовать ссылки как способ захвата экземпляров компонентов и вызова на них методов. Это неправильный способ использования рефери, когда рефери быстро уходят на юг.
Правильный (и очень полезный) способ использования ссылок - это когда вы используете их для получения некоторого значения из DOM. Например, если у вас есть поле ввода, прикрепляющее ссылку к этому входу, то получение значения позже через ссылку вполне нормально. Без этого способа вам нужно будет пройти довольно согласованный процесс для поддержания вашего поля ввода в актуальном состоянии либо с вашим локальным состоянием, либо с вашим хранилищем потоков, что кажется ненужным.
Редактировать 2019: Здравствуйте, друзья будущего. В дополнение к тому, что я упоминал несколько лет назад ^, с помощью React Hooks ссылки также являются отличным способом отслеживать данные между рендерами и не ограничиваются только захватом узлов DOM.
источник
refs
и получите значение состояния. На самом деле это кажется действительно красивым узором.TL; DR Вообще говоря,
refs
идите вразрез с декларативной философией React , поэтому вы должны использовать их в крайнем случае. Используйте поstate / props
возможности.Чтобы понять, где вы используете
refs
vsstate / props
, давайте рассмотрим некоторые принципы дизайна, которым следует React.Документация Per React о
refs
Принципы проектирования аварийных люков в соответствии с принципами React
Это означает, что команда React предлагает избегать
refs
и использоватьstate / props
для всего, что можно сделать реактивным / декларативным способом.@Tyler McGinnis дал очень хороший ответ , заявив, что
Хотя вы можете это сделать, вы будете работать против философии React. Если у вас есть значение во входных данных, оно наверняка исходит из
state / props
. Чтобы код оставался последовательным и предсказуемым, вам также следует придерживатьсяstate / props
этого правила. Я признаю тот факт, чтоrefs
иногда это дает вам более быстрое решение, поэтому, если вы делаете доказательство концепции, приемлемо быстрое и грязное .Это оставляет нам несколько случаев использования бетона для
refs
источник
Это старый пост
Я поделюсь своим небольшим опытом по одному делу по этому поводу.
Я работал над большим компонентом (414 строк) с большим количеством «динамических» входных данных и большим количеством задействованных кэшированных данных. (Я работаю над страницей не один, и мои чувства подсказывают мне, что структуру кода, вероятно, можно было бы разделить лучше, но дело не в этом (ну, может быть, но я имею дело с этим)
Сначала я работал с состоянием, чтобы обрабатывать значения входных данных:
и, конечно же, во входах:
Рендеринг был настолько тяжелым, что изменение ввода было прерывистым, как **** (не пытайтесь удерживать клавишу нажатой, текст появится только после паузы)
Я был уверен, что смогу избежать этого, используя ссылки.
закончилось так:
и во входах:
[ну, в моем случае Input был Material-UI TextField, так что это было:
]
Благодаря этому нет повторного рендеринга, ввод плавный, функциональность работает точно так же. Это сэкономит циклы и вычисления, а значит, и энергию. Сделайте это для земли x)
Мой вывод: может даже понадобиться useRef для значений input.
источник