首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React refs与组件

React refs与组件
EN

Stack Overflow用户
提问于 2014-09-20 04:02:11
回答 2查看 42.7K关注 0票数 16

我有一个React表单,它有一个用于呈现下拉列表的组件,因为选项来自API。但是,我不能访问嵌入式组件的ref。我正在整理我的第一张表格,并试图理解处理这一问题的最佳方法。

代码语言:javascript
复制
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>
    );
  }
});
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-20 04:32:33

最好将ref视为callback attribute,而不再依赖于refs对象。如果使用refs对象,请避免访问子组件的refs。您应该将refs视为私有访问器,而不是组件的API的一部分。仅将组件实例上公开的方法视为其公共API。

对于这种情况,我建议从提交事件中获取表单,并根据需要遍历其子表单元素。添加name属性,因为这是在标准表单提交中标识表单元素的方式,这样您就完全不需要refs了:

代码语言:javascript
复制
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>
    );
  }
});

Update 2016-09-21:根据 文档中的指导,修改建议以避免所有refs对象。

票数 24
EN

Stack Overflow用户

发布于 2014-09-20 04:14:15

复合组件可以有其自己的ref;您可以深入到它们,以访问组件层次结构的更下方的ref。

示例:

代码语言:javascript
复制
<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>

然而,ssorallen是正确的-如果可能的话,你应该尽量避免这种情况。相反,您应该将回调传递给子对象:

代码语言:javascript
复制
<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({
  getInitialState: function() {
    return { text: "" };
  },

  render: function() {
    return (
      <div>
        <Child onChange={this.updateText} />
        <div><button onClick={this.handleClick}>Alert Text</button></div>
      </div>
    );
  },
  
  handleClick: function() {
    alert(this.state.text);
  },

  updateText: function(text) {
    this.setState({text: text});
  }
});

var Child = React.createClass({
  render: function() {
    return <textarea onChange={this.handleChange} />;
  },

  handleChange: function(evt) {
    this.props.onChange(evt.target.value);
  }
});

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

或者在子对象中公开一个公共API:

代码语言:javascript
复制
<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.getText());
  }
});

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

  getText: function() {
    return this.getDOMNode().value;
  }
});

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

或者使用一些其他数据流管理(例如,流量、事件等)。

票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25941585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档