React Demo

[TOC]

React.findDOMNode()

React.findDOMNode()从组件获取真实DOM的节点。

var MyComponent = React.createClass({
        handleClick:function(){
            React.findDOMNode(this.refs.myTextInput).focus();
        },
        render:function(){
            return (
                <div>
                    <input type="text" ref="myTextInput" />
                    <input type="button" value="Focus the text input" onClick={this.handleClick}/>
                </div>
            );
        }
    });
    React.render(
        <MyComponent />,
        document.getElementById('example')
    );

ref

ref与React.findDOMNode()结合使用,该功能是为了结合现有非React类库,通过ref/refs可以获取得到组件实例,进而取得原生节点。

var Test = React.createClass({
    componentDidMount(){
      alert(React.findDOMNode(this.refs.content).innerHTML);
    },
    render(){
        return <div>
            <h3>header</h3>
            <div ref='content'>content</div>
        </div>;
    }
});

React.render(<Test />,document.getElementById('example'));

this.state

var LikeButton = React.createClass({
        getInitialState:function(){
            return {liked:false};
        },
        handleClick:function(event){
            this.setState({liked: !this.state.liked});
        },
        render:function(){
            var text = this.state.liked ? 'like' : 'haven\'t liked';
            return (
                <p onClick={this.handleClick}>
                    You {text} this.Click to toggle.
                </p>
            ); 
        }
    });
    React.render(
        <LikeButton />,
        document.getElementById('example')
    );

获取表单值

用户在表单填入的内容,属于用户跟组件的互动,所以不能用this.props读取。

  var Input = React.createClass({
    getInitialState:function(){
        return {value:'Hello!'};
    },
    handleChange:function(event){
        this.setState({value:event.target.value});
    },
    render:function(){
        var value = this.state.value;
        return (
            <div>
                <input type="text" value={value} onChange={this.handleChange} />
                <p>{value}</p>
            </div>
        );
    }
});
React.render(<Input />,document.getElementById('example'));

上面代码中,文本输入框的值,不能用this.props.value读取,而要定义一个onChange事件的回调函数,通过event.target.value读取用户输入的值。textarea元素、select元素、radio元素都属于这种情况。

  • value/checked属性设置后,用户输入无效
  • textarea的值要设置在value属性上
  • select的value属性可以是数组,不建议使用option的selected属性
  • input/textarea的onChange用户每次输入都会触发
  • radio/checkbox点击后也会触发onChange

如果设置了value属性,组件变为受控组件,用户无法输入,除非程序改变value属性。受控组件可以通过监听handleChange事件,结合state来改变input值。

ajax

具体见评论框示例中,ajax也可直接写在componentDidMount中。

评论框Demo

// 代码摘自官网教程
var CommentBox = React.createClass({
    getInitialState: function() {
        return {data: []};
    },
  loadCommentsFromServer: function() {
      getInitialState: function() {
        return {data: []};
      },
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },

  componentDidMount: function() {
    this.loadCommentsFromServer();
    setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  },
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList data={this.state.data} />
        <CommentForm />
      </div>
    );
  }
});

var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.data.map(function(comment) {
      return (
        <Comment author={comment.author} key={comment.id}>
          {comment.text}
        </Comment>
      );
    });
    return (
      <div className="commentList">
        {commentNodes}
      </div>
    );
  }
});

var CommentForm = React.createClass({
  render: function() {
    return (
      <form className="commentForm">
        <input type="text" placeholder="Your name" />
        <input type="text" placeholder="Say something..." />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

ReactDOM.render(
  <CommentBox url="/api/comments" pollInterval={2000} />,
  document.getElementById('content')
);

若child需要向parent传递值,则

//修改以下两个模块的代码
var CommentForm = React.createClass({
  getInitialState: function() {
    return {author: '', text: ''};
  },
  handleAuthorChange: function(e) {
    this.setState({author: e.target.value});
  },
  handleTextChange: function(e) {
    this.setState({text: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    var author = this.state.author.trim();
    var text = this.state.text.trim();
    if (!text || !author) {
      return;
    }
    this.props.onCommentSubmit({author: author, text: text});
    this.setState({author: '', text: ''});
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input
          type="text"
          placeholder="Your name"
          value={this.state.author}
          onChange={this.handleAuthorChange}
        />
        <input
          type="text"
          placeholder="Say something..."
          value={this.state.text}
          onChange={this.handleTextChange}
        />
        <input type="submit" value="Post" />
      </form>
    );
  }
});
var CommentBox = React.createClass({
  loadCommentsFromServer: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  handleCommentSubmit: function(comment) {
    var comments = this.state.data;
    <!-- Optimistically set an id on the new comment. It will be replaced by an id generated by the server. In a production application you would likely not use Date.now() for this and would have a more robust system in place.-->
    comment.id = Date.now();
    var newComments = comments.concat([comment]);
    this.setState({data: newComments});
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: comment,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        this.setState({data: comments});
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  getInitialState: function() {
    return {data: []};
  },
  componentDidMount: function() {
    this.loadCommentsFromServer();
    setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  },
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList data={this.state.data} />
        <CommentForm onCommentSubmit={this.handleCommentSubmit} />
      </div>
    );
  }
});
文章目录
  1. 1. React.findDOMNode()
  2. 2. ref
  3. 3. this.state
  4. 4. 获取表单值
  5. 5. ajax
  6. 6. 评论框Demo