React Intro

Version:15.01

React是一个构建用户界面的JS库。

  1. 仅仅用来做UI
    许多人用React做MVC中的View。由于React对View之外的技术栈不做限制,要在一个已有的项目中使用一些小特性是非常容易的。
  2. 虚拟DOM
    React抽象了DOM,事编程模型更加简单,性能更好。React也可以使用Node在服务端渲染,同时它也可以使用React Native支持原生应用。
  3. 数据流
    React实现单向响应式数据流,这样就减少了模板并且相对于传统的数据绑定更加容易推理。

**一个简单的组件
**
React组建实现了一个render()方法,它接受数据输入,返回要显示的内容。这个例子使用名为JSX的类XML语法。传入组建的输入数据,render()可以通过this.props获取。
使用React时,JSX是可选的而非必须。通过点击“Compiled JS”可以查看JSX编译器产生的原生JS代码。

JSX代码:

var HelloMessage = React.createClass({
  render: function() {
    return 
Hello {this.props.name}
; } }); ReactDOM.render(, mountNode);

对应JS代码:

"use strict";

var HelloMessage = React.createClass({
  displayName: "HelloMessage",

  render: function render() {
    return React.createElement(
      "div",
      null,
      "Hello ",
      this.props.name
    );
  }
});

ReactDOM.render(React.createElement(HelloMessage, { name: "John" }), mountNode);

**一个状态组件
**
除了接受输入数据(通过this.props),组件也可以维持一个内部状态数据(通过this.state)。当一个组件的状态数据改变时,渲染的标签也会通过重新激发render()被更新。

JSX代码:

var Timer = React.createClass({
  getInitialState: function() {
    return {secondsElapsed: 0};
  },
  tick: function() {
    this.setState({secondsElapsed: this.state.secondsElapsed + 1});
  },
  componentDidMount: function() {
    this.interval = setInterval(this.tick, 1000);
  },
  componentWillUnmount: function() {
    clearInterval(this.interval);
  },
  render: function() {
    return (
      
Seconds Elapsed: {this.state.secondsElapsed}
); } }); ReactDOM.render(, mountNode);

对应JS代码:

"use strict";

var Timer = React.createClass({
  displayName: "Timer",

  getInitialState: function getInitialState() {
    return { secondsElapsed: 0 };
  },
  tick: function tick() {
    this.setState({ secondsElapsed: this.state.secondsElapsed + 1 });
  },
  componentDidMount: function componentDidMount() {
    this.interval = setInterval(this.tick, 1000);
  },
  componentWillUnmount: function componentWillUnmount() {
    clearInterval(this.interval);
  },
  render: function render() {
    return React.createElement(
      "div",
      null,
      "Seconds Elapsed: ",
      this.state.secondsElapsed
    );
  }
});

ReactDOM.render(React.createElement(Timer, null), mountNode);

**一个应用(Todo)
**
使用props和states,我们可以整合一个小的Todo应用。这个例子使用state跟踪当前项目列表和用户输入文本。虽然事件处理器看似在行内渲染,但是它们会被收集并使用事件代理实现。

JSX代码:

var TodoList = React.createClass({
  render: function() {
    var createItem = function(item) {
      return 
  • {item.text}
  • ; }; return
      {this.props.items.map(createItem)}
    ; } }); var TodoApp = React.createClass({ getInitialState: function() { return {items: [], text: ''}; }, onChange: function(e) { this.setState({text: e.target.value}); }, handleSubmit: function(e) { e.preventDefault(); var nextItems = this.state.items.concat([{text: this.state.text, id: Date.now()}]); var nextText = ''; this.setState({items: nextItems, text: nextText}); }, render: function() { return (

    TODO

    ); } }); ReactDOM.render(, mountNode);

    对应JS代码:

    'use strict';
    
    var TodoList = React.createClass({
      displayName: 'TodoList',
    
      render: function render() {
        var createItem = function createItem(item) {
          return React.createElement(
            'li',
            { key: item.id },
            item.text
          );
        };
        return React.createElement(
          'ul',
          null,
          this.props.items.map(createItem)
        );
      }
    });
    var TodoApp = React.createClass({
      displayName: 'TodoApp',
    
      getInitialState: function getInitialState() {
        return { items: [], text: '' };
      },
      onChange: function onChange(e) {
        this.setState({ text: e.target.value });
      },
      handleSubmit: function handleSubmit(e) {
        e.preventDefault();
        var nextItems = this.state.items.concat([{ text: this.state.text, id: Date.now() }]);
        var nextText = '';
        this.setState({ items: nextItems, text: nextText });
      },
      render: function render() {
        return React.createElement(
          'div',
          null,
          React.createElement(
            'h3',
            null,
            'TODO'
          ),
          React.createElement(TodoList, { items: this.state.items }),
          React.createElement(
            'form',
            { onSubmit: this.handleSubmit },
            React.createElement('input', { onChange: this.onChange, value: this.state.text }),
            React.createElement(
              'button',
              null,
              'Add #' + (this.state.items.length + 1)
            )
          )
        );
      }
    });
    
    ReactDOM.render(React.createElement(TodoApp, null), mountNode);
    

    一个使用外部插件的组件

    React非常灵活,提供了和其他库和框架交互的钩子。本例使用marked(一个外部Markdown库)来实时转换文本域中的内容。

    JSX代码:

    var MarkdownEditor = React.createClass({
      getInitialState: function() {
        return {value: 'Type some *markdown* here!'};
      },
      handleChange: function() {
        this.setState({value: this.refs.textarea.value});
      },
      rawMarkup: function() {
        return { __html: marked(this.state.value, {sanitize: true}) };
      },
      render: function() {
        return (
          

    Input