React.js入门教程

React js Tutorial: Now is Your Time to Try It, Right in Your Browser

ReactJS教程: 开始使用Facebook的ReactJS

React Components

React Properties

React State

React Flux的一些理解(React Flux入门教程)

React is “A JavaScript library for building user interfaces”.

这篇关于react的教程涉及在实际应用中react的最佳实践.如果没听说过react,可以访问它的 官网

我们将要做些什么

我们将会创建一个简单的页面,包含React component 和 一些 sub component. 它们与数据双向绑定. 而且还会涉及到 props, state 和 event management.

创建 Main Component

var MainV = React.createClass({});

渲染到屏幕上:

React.renderComponent(new MainV(), document.body);

接下来我们添加一些方法

  • getDefaultProps: 在渲染之前调用, 第一个调用的方法, 只调用一次
  • getInitialState: getDefaultProps之后调用,用于返回component的默认状态,只调用一次
  • render: 用于渲染component, 上一个函数之后调用

让component渲染简单的一个div和一些文本:

 
return React.DOM.div({ className: 'root' }, 'Simple div')

 
var MainV = React.createClass({ getDefaultProps: function(){ return {

    <span class="p">}</span>
<span class="p">},</span>
<span class="nx">getInitialState</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">{</span>

    <span class="p">}</span>
<span class="p">},</span>
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">React</span><span class="p">.</span><span class="nx">DOM</span><span class="p">.</span><span class="nx">div</span><span class="p">({</span>
        <span class="nx">className</span><span class="o">:</span> <span class="s1">&#39;root&#39;</span><span class="p">,</span>
    <span class="p">},</span> <span class="s1">&#39;Simple div&#39;</span><span class="p">);</span>
<span class="p">}</span>

});

React.renderComponent(new MainV, document.body);

component同时具有propsstate可能有些同学会疑惑. props在整个component的生命周期中都是不可改变的.而stat是可以改变的. state的任何改变都会调用render函数

添加一些数据

我们使用一个颜色表来作为例子. 创建一个rows变量和把它作为一个props传递给mainV. 当我们实例化一个React类的时候就会传递一个对象,而这个对象就是这个实例的props.

var getData = function getData(){
    return [
        {
            color: "red",
            value: "#f00"
        },
        {
            color: "green",
            value: "#0f0"
        },
        {
            color: "blue",
            value: "#00f"
        },
        {
            color: "cyan",
            value: "#0ff"
        },
        {
            color: "magenta",
            value: "#f0f"
        },
        {
            color: "yellow",
            value: "#ff0"
        },
        {
            color: "black",
            value: "#000"
        }
    ]
}
var rows = getData();
var mainV = new MainV({
    rows: rows
});
React.renderComponent(mainV, document.body);

在React类里添加:

getDefaultProps: function(){
    return {
        rows: null
    }
},

假设有一个对象和对象里面有些键值.如果没有任何东西传递给component,而你尝试去获取一个对象的值的时候就会报错,为了防止这样的事情发生你需要检查对象是否存在.如果你使用getDefaultProps你应该不需要检查因为它就是一直存在的.这是官方的用法.

现在让我们使mainV渲染一些有颜色的div

首先我们引入underscore

更新render函数:

render: function(){
    return React.DOM.div({
        className: 'root'
        },
        _.map(this.props.rows, function(row) {
            return React.DOM.div({
                className: 'box'
            })
        })
    );
}

React.DOM.div接受的第二个参数到底是神马呢? 可以是简单的文本, 一个数组, 一个二维数组也是可以的.

现在我们来加些CSS

.box {
    width: 50px;
    height: 50px;
    background-color: black;
}

现在代码应该是长这样的:

var getData = function getData(){
    return [
        {
            color: "red",
            value: "#f00"
        },
        {
            color: "green",
            value: "#0f0"
        },
        {
            color: "blue",
            value: "#00f"
        },
        {
            color: "cyan",
            value: "#0ff"
        },
        {
            color: "magenta",
            value: "#f0f"
        },
        {
            color: "yellow",
            value: "#ff0"
        },
        {
            color: "black",
            value: "#000"
        }
    ]
};

var MainV = React.createClass({ getDefaultProps: function(){ return { rows: null } }, getInitialState: function() { return {

    <span class="p">}</span>
<span class="p">},</span>
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">React</span><span class="p">.</span><span class="nx">DOM</span><span class="p">.</span><span class="nx">div</span><span class="p">({</span>
        <span class="nx">className</span><span class="o">:</span> <span class="s1">&#39;root&#39;</span><span class="p">,</span>
    <span class="p">},</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">rows</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">row</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nx">React</span><span class="p">.</span><span class="nx">DOM</span><span class="p">.</span><span class="nx">div</span><span class="p">({</span>
                <span class="nx">className</span><span class="o">:</span> <span class="s1">&#39;box&#39;</span><span class="p">,</span>
                <span class="nx">style</span><span class="o">:</span> <span class="p">{</span>
                    <span class="nx">backgroundColor</span><span class="o">:</span> <span class="nx">row</span><span class="p">.</span><span class="nx">value</span>
                <span class="p">}</span>
            <span class="p">},</span> <span class="nx">row</span><span class="p">.</span><span class="nx">color</span><span class="p">)</span>
    <span class="p">}));</span>
<span class="p">}</span>

});

var rows = getData(), mainV = new MainV({ rows: rows });

React.renderComponent(mainV, document.body);

添加子组件

创建ItemRenderer用来完成一个简单的任务: 渲染数据项.

var ItemRendererV = React.createClass({

<span class="nx">getDefaultProps</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span>
    <span class="k">return</span> <span class="p">{</span>
        <span class="nx">color</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
        <span class="nx">value</span><span class="o">:</span> <span class="kc">null</span>
    <span class="p">}</span>
<span class="p">},</span>

<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span>
    <span class="k">return</span> <span class="nx">React</span><span class="p">.</span><span class="nx">DOM</span><span class="p">.</span><span class="nx">div</span><span class="p">({</span>
        <span class="nx">className</span><span class="o">:</span> <span class="s1">&#39;box&#39;</span><span class="p">,</span>
        <span class="nx">style</span><span class="o">:</span> <span class="p">{</span>
            <span class="nx">backgroundColor</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">value</span>
        <span class="p">}</span>
    <span class="p">},</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">color</span><span class="p">)</span>
<span class="p">}</span>

})

ItemRendererV只是接受两个props(颜色和对应的值)然后在render方法里面渲染.

现在我们更新一下MainV. render方法里面渲染ItemRendererV

render: function(){
    return React.DOM.div({
            className: 'root'
        },
        _.map(this.props.rows, function(row){
            return new ItemRendererV(row);
        })
    )
}

创建一个ItemRendererV的实例然后传了一个row对象. 这个row对象会变成ItemRendererV的props.

写到这里运行一下报了一个这样的错:

加些State

上面我们说到的props是不可改变的.

改变state很简单我们可以这样:

this.setState({key: 'value'})

但是永远不要这样:

this.state.key = 'another value'

this.state.key 只能用来获取值,这是只读的.

当你使用了setState来改变数据的时候this.state不会被立即更新. 如果你想要一发证改变就获取数据可以这样做:

this.setState({key: 'another value'}, function(){alert(this.state.key)})

现在我们可以为每一个渲染项目它们是否得选中的状态加一个state:

getInitialState: function(){
    return {
        selected: false
    }
},

render: function(){ return React.DOM.div({ className: 'box ' + (this.state.selected ? 'selected' : 'unselected'), onClick: function(){this.setState({selected: !this.state.selected})}.bind(this), style: { backgroundColor: this.props.value } }, this.props.color) }

添加CSS:

.selected {
    opacity: 1;
}

.unselected { opacity: 0.5; }

发生一些事情的时候:events

You might also want to alert the parent view that a new item has been selected. This is done by adding a prop value with a function when instancing the item renderer. Then the item renderer will call the function when is required. Change the render method of MainV:

你或许想当一个项被选中的时候通知父视图(parent view). 通过实例化一个item renderer时通过函数添加prop已经办到了.item renderer会在需要时调用函数.改变一下mainVrender方法:

onItemRendererSelect: function(data){
    alert(data.color)
},
render: function() {  
var this = this; return React.DOM.div({ className: 'root' }, .map(this.props.rows, function(row) { return new ItemRendererV({ data: row, onSelect: _this.
onItemRendererSelect }); }) ) }

我们现在需要传递两样不同的东西:一些数据和一个函数. onSelect函数会被item renderer调用.

改一下item renderer:

getDefaultProps: function(){
    return {
        data: {
            color: null,
            value: null
        },
        onSelect: null
    }
},

this.props.color 改成 this.props.data.color(还有value)

现在我们需要使item renderer 调用 onSelect 函数

__onClick: function(){
    this.setState({selected: !this.state.selected}, function(){
        if(this.state.selected && this.props.onSelect){
            this.props.onSelect(this.props.data);
        }
    })
},

render: function(){ return React.DOM.div({ className: 'box ' + (this.state.selected ? 'selected' : 'unselected'), onClick: this.__onClick, style: { backgroundColor: this.props.data.value } }, this.props.data.color) }

完整的Dome在这里

更进一步

原文作者给出了一个更具有效果的 Demo

« 返回