React refs с компонентами

У меня есть форма React, у которой есть компонент, используемый для визуализации выпадающего списка, потому что параметры исходят из API. Однако я не могу получить доступ к ref для встроенного компонента. Я собираю свою первую форму и пытаюсь понять, как лучше подойти к ней.

var ActivityForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();

    var noteCategoryId = this.refs.note_category_id.getDOMNode().value.trim();
    var content = this.refs.content.getDOMNode().value.trim();

    if (!category || !content) {
      return;
    }

    // this.props.onCommentSubmit({author: author, text: text});

    this.refs.note_category_id.getDOMNode().value = '';
    this.refs.content.getDOMNode().value = '';
    return;
  },
  render: function() {
    return (
      <div className="new-activity">
        <h3>New Activity</h3>
        <form onSubmit={this.handleSubmit}>
          <textarea ref='content' />
          <br />

          <label>Category</label>
          <ActivityFormCategoryDropdown /> # THE REF IN THIS COMPONENT ISN'T ACCESSIBLE
          <br />

          <input type="submit" value="Add Activity" />
        </form>
      </div>
    );
  }
});

Ответы

Ответ 1

Предпочтительно рассматривать ref как атрибут обратного вызова и больше не зависеть от объекта refs. Если вы используете объект refs, избегайте доступа к refs компонентов-потомков. Вы должны рассматривать refs как частный аксессор, а не компонент API-интерфейса компонента. Рассматривайте только методы, выставленные на экземпляре компонента, как открытый API.

В этом случае я предлагаю захватить форму из события submit и, при необходимости, перебирать элементы своей дочерней формы. Добавьте атрибуты name, так как элементы формы идентифицируются в стандартном представлении формы, а затем вам не нужно refs вообще:

var ActivityForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var form = e.target;

    // Use the standard [`HTMLFormElement.elements`][1] collection
    //
    // [1]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/elements
    var content = form.elements['content'].value;

    // do more things with other named form elements
  },
  render: function() {
    return (
      <div className="new-activity">
        <h3>New Activity</h3>
        <form onSubmit={this.handleSubmit}>
          <textarea name='content' />
          <br />

          <label>Category</label>
          <ActivityFormCategoryDropdown />
          <br />

          <input type="submit" value="Add Activity" />
        </form>
      </div>
    );
  }
});

Обновление 2016-09-21: пересмотреть предложение, чтобы избежать refs объекта все вместе на руководство из ref String Attribute docs.

Ответ 2

Компонентные компоненты могут иметь свои собственные ссылки; вы можете обратиться к ним, чтобы получить доступ к refs дальше по иерархии компонентов.

Пример:

<script src="http://fb.me/react-with-addons-0.11.2.js"></script>
<script src="http://fb.me/JSXTransformer-0.11.2.js"></script>

<div id="app"></div>

<script type="text/jsx">
/** @jsx React.DOM */

var Parent = React.createClass({
  render: function() {
    return (
      <div>
        <Child ref="child" />
        <div><button onClick={this.handleClick}>Alert Text</button></div>
      </div>
    );
  },
  
  handleClick: function() {
    alert(this.refs.child.refs.textarea.getDOMNode().value);
  }
});

var Child = React.createClass({
  render: function() {
    return <textarea ref="textarea" />;
  }
});

React.renderComponent(<Parent />, document.getElementById("app"));
</script>