Использовать состояние или ссылки в компонентах формы React.js?

87

Я начинаю с 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: ''
  });
});

Я не вижу плюсов и минусов двух альтернатив, если они существуют. Спасибо.

  • 0
    Я что-то здесь упускаю? Почему вы не используете объект события, чтобы получить значения формы? Это, кажется, единственная причина использовать форму здесь, в первую очередь. Если вы не используете поведение отправки по умолчанию и имеете ссылки на входные данные, вам не нужно заключать их в форму.
Теги:

3 ответа

109
Лучший ответ

Краткая версия: избегать ссылок.


Они плохо подходят для ремонтопригодности и теряют большую простоту рендеринга модели WYSIWYG.

У вас есть форма. Вам нужно добавить кнопку, которая сбрасывает форму.

  • рефов:
    • манипулировать DOM
    • render описывает, как выглядела форма 3 минуты назад.
  • состояние
    • SetState
    • render описывает, как выглядит форма.

У вас есть поле номера CCV на входе и некоторые другие поля в приложении, которые являются числами. Теперь вам нужно обеспечить, чтобы пользователь вводил только числа.

  • рефов:
    • добавить обработчик onChange (не будем ли мы использовать refs, чтобы этого избежать?)
    • манипулировать dom в onChange, если это не число
  • состояние
    • У вас уже есть обработчик onChange
    • добавить инструкцию if, если она недействительна ничего не делает
    • render вызывается только в том случае, если он будет производить другой результат

Эх, неважно, премьер-министр хочет, чтобы мы просто сделали красную коробку, если она недействительна.

  • рефов:
    • сделать onChange обработчик просто вызвать forceUpdate или что-то еще?
    • сделать вывод вывода на основе... huh?
    • Где мы получаем значение для проверки в рендере?
    • вручную манипулировать элементом className dom свойство
    • Я потерял
    • переписать без ссылок?
    • читать из dom в рендеринге, если мы монтируем в противном случае, допустим?
  • состояние:
    • удалить оператор if
    • сделать рендеринг на основе this.state

Нам нужно вернуть управление родительскому элементу. Данные теперь находятся в реквизитах, и нам нужно реагировать на изменения.

  • рефов:
    • реализовать componentDidMount, componentWillUpdate и componentDidUpdate
    • вручную разделить предыдущие реквизиты
    • манипулировать dom с минимальным набором изменений
    • эй! мы внедряем реакцию в реакции...
    • там больше, но мои пальцы больно
  • состояние:
    • sed -e 's/this.state/this.props/' 's/handleChange/onChange/' -i form.js

Люди думают, что рефссы "легче", чем держать его в состоянии. Это может быть правдой в течение первых 20 минут, это не соответствует моему опыту после этого. Положите свое "я", чтобы сказать "Да, я сделаю это через 5 минут", а не "Конечно, я просто переписал несколько компонентов".

  • 0
    Привет @ FakeRainBrigand, спасибо за ответ. Когда вы говорите, что в ссылках мы манипулируем DOM, вы говорите о Virtual DOM, не так ли? Конечно, если есть какие-либо изменения в Virtual DOM, это подразумевает также изменение в «реальном» DOM, но то же самое относится и к состоянию.
  • 3
    Не могли бы вы немного подробнее рассказать о sed -e 's / this.state / this.props /' s / handleChange / onChange / '-i form.js?
Показать ещё 12 комментариев
76

Я видел, как несколько человек ссылаются на вышеупомянутый ответ как на причину "никогда не использовать ссылки", и я хочу дать свое (а также несколько других участников React, с которыми я говорил).

"Не использовать ссылки refs" правильно, когда вы говорите об их использовании для экземпляров компонентов. Значит, вы не должны использовать refs как способ захвата экземпляров компонентов и методов вызова на них. Это неправильный способ использования refs, и когда refs быстро выходит на юг.

Правильный (и очень полезный) способ использования ссылок - это когда вы используете их для получения значения из DOM. Например, если у вас есть поле ввода, содержащее ссылку на этот ввод, то захват значения позже через ref просто отлично. Без этого вам нужно пройти довольно организованный процесс, чтобы обновлять ваше поле ввода либо в вашем локальном штате, либо в вашем хранилище флюсов, что кажется ненужным.

  • 3
    Ваш последний абзац имеет смысл, но можете ли вы уточнить свой второй абзац? Что является конкретным примером захвата экземпляра компонента и вызова метода, который будет считаться неправильным?
  • 2
    Я бы согласился с этим. Я использую ссылки до тех пор, пока мне не понадобится проверка или манипулирование значением поля. Если мне нужно проверить на изменение или изменить значения программно, то я использую состояние.
Показать ещё 2 комментария
2

TL; DR Вообще говоря, refs идти против React декларативной философии, поэтому вы должны использовать их в качестве крайней меры. Используйте state / props, когда это возможно.


Чтобы понять, где вы используете refs vs state / props, рассмотрим некоторые из принципов проектирования, которые следует за реакцией.

Per React документация о refs

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

Взаимодействовать с принципами дизайна Escape Hatches

Если какой-либо шаблон, который полезен для создания приложений, трудно выразить декларативным образом, мы предоставим ему императивный API. (и они ссылаются на ссылки здесь)

Это означает, что команда React предлагает избегать refs и использовать state / props для всего, что может быть сделано реактивно/декларативно.

@Tyler McGinnis предоставил очень хороший ответ , указав также, что

Правильный (и очень полезный) способ использования refs - это когда вы используете их для получения значения из DOM...

Пока вы можете это сделать, вы будете работать против философии React. Если у вас есть значение на входе, это, безусловно, происходит от state / props. Чтобы код был согласованным и предсказуемым, вы также должны придерживаться state / props. Я признаю тот факт, что refs иногда дает вам более быстрое решение, поэтому, если вы сделаете доказательство концепции, то быстро и грязно допустимо.

Это оставляет нам несколько конкретных вариантов использования для refs

Управление фокусом, выбором текста или воспроизведением мультимедиа. Выполнение обязательных анимаций. Интеграция с сторонними библиотеками DOM.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню