node.js学习笔记之React

React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。

ReactJS官网地址:http://facebook.github.io/react/

Github地址:https://github.com/facebook/react

React认为一个组件应该具有如下特征:

(1)可组合(Composeable):一个组件易于和其它组件一起使用,或者嵌套在另一个组件内部。如果一个组件内部创建了另一个组件,那么说父组件拥有(own)它创建的子组件,通过这个特性,一个复杂的UI可以拆分成多个简单的UI组件;

(2)可重用(Reusable):每个组件都是具有独立功能的,它可以被使用在多个UI场景;

(3)可维护(Maintainable):每个小的组件仅仅包含自身的逻辑,更容易被理解和维护;

我们新建一个html文件,引用react.js和JSXTransformer.js这两个js文件。html模板如下(js路径改成自己的):

<!DOCTYPE html><html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="../build/browser.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel">
      // ** Our code goes here! **    </script>
  </body></html>

script的type是text/babel,这是因为 React 独有的 JSX 语法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type="text/babel" 。

其次,上面代码一共用了三个库: react.js 、react-dom.js 和 Browser.js ,它们必须首先加载。其中,react.js 是 React 的核心库,react-dom.js 是提供与 DOM 相关的功能,Browser.js 的作用是将 JSX 语法转为 JavaScript 语法,这一步很消耗时间,实际上线的时候,应该将它放到服务器完成。

下面开始看react该怎么写,还是传统的老规矩 hello word:

<!DOCTYPE html>
<html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="../build/browser.min.js"></script>
  </head>
  <body>
  
    <div id="example"></div>
    
    <script type="text/babel">
    
      ReactDOM.render(<h1>hello word</h1>,document.getElementById('example'));
      
    </script>
  </body>
</html>

在上例的body中,有一个div,id是example, 然后由react的渲染器把h1标签渲染到该div中。

ReactDOM.render(DOM节点,被插入的父节点);

这一句代码是最常用也是非常必要的一句。 这句中有个很重要的地方就是html语法和js语法的混写,这是jsx语法的特点,在jsx语法里,遇到 尖括号就按照html来解析,遇到花括号就按照js语法去解析。下面这个例子更能说明jsx语法的写法:

 var list = ["word","man","boy"];
  ReactDOM.render(
          <div>
            {
              list.map(function (name){
              return <div> hello {name}</div>
               })
          }
          </div>,document.getElementById('example'));
</script>

最终的结果是:

hello word

hello man

hello boy


这里有一点需要说明的是 ReactDOM.render 渲染器的第一个参数里,有且只能有一个顶级节点,不能有多个并列,否则会报错。JSX 允许直接在模板插入 JavaScript 变量。如果这个变量是一个数组,则会展开这个数组的所有成员。

var list = [<h1>word</h1>,<h1>man</h1>,<h1>boy</h1>];
  ReactDOM.render(<div>{list}</div>,document.getElementById('example'));
</script>

最终结果是:

word

man

boy

React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。React.createClass 方法就用于生成一个组件类:

var HelloWord = React.createClass({
    render:function(){
        return <p>hello {this.props.name}</p>
    }
});
 ReactDOM.render(<HelloWord name="喵星人"/>,document.getElementById('example'));

最终结果是:

hello 喵星人


上例中用React.createClass创建了一个组件类HelloWord,这里有一点需要注意:组件类名字的首字母必须是大写的,否则会报错。React.createClass接收一个对象,对象中必须有render属性,render属性的值一般都是写成一个函数,然后返回一个DOM对象,别忘了上面说的,这个DOM对象有且只能有一个顶级节点,否则会报错。

我们在上面的代码的return 里会看到有这么一段:this.props.name,然后在ReactDom.render中的第一个参数里会看到标签有一个属性name="喵星人",这里需要记住的一点是name="喵星人"看上去就像在对函数传参数,而this.props.name就是对参数的接收。

添加组件属性,有一个地方需要注意,就是 class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。


this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点。

var NotesList = React.createClass({
  render: function() {
    return (
      <ol>
      {
        this.props.children.map(function (child) {
          return <li>{child}</li>;
        })
      }
      </ol>
    );
  }});ReactDOM.render(
  <NotesList>
    <span>hello</span>
    <span>world</span>
    <p>main</p>
  </NotesList>,
  document.getElementById('example'));

最终运行结果:

  1. hello

  2. world


3. main



2 和3之间的换行是因为p标签会自带一个换行,li标签也会有一个换行,所以中间就有了一个空白行.


组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI
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>
    );
  }});ReactDOM.render(
  <LikeButton />,
  document.getElementById('example'));

最终结果:

You haven't liked this. Click to toggle.

当在文字上点击时会变成:

You like this. Click to toggle.

然后一直点击就会在两句英文之间来回切换。

这里需要注意的是 getInitialState 是React默认的属性,需要返回一个对象,可以是NULL或者其他,表示初始状态,返回的对象中可以不止有一个属性,修改这些状态可以使用react提供的方法this.setState(对象), 这里的对象可以只修改初始状态中的某一个属性,也可以同时修改多个。当任何一个状态改变的时候react就会重新调用 render属性所指向的函数,也就意味着会重新渲染该组件。


组件的生命周期分成三个状态:

Mounting:已插入真实 DOM

Updating:正在被重新渲染

Unmounting:已移出真实 DOM

React 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数。

componentWillMount()

componentDidMount()

componentWillUpdate(object nextProps, object nextState)

componentDidUpdate(object prevProps, object prevState)

componentWillUnmount()

此外,React 还提供两种特殊状态的处理函数。

componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用

shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用

var Hello = React.createClass({
  getInitialState: function () {
    return {
      opacity: 1.0
    };
  },

  componentDidMount: function () {
    this.timer = setInterval(function () {
      var opacity = this.state.opacity;
      opacity -= .05;
      if (opacity < 0.1) {
        opacity = 1.0;
      }
      this.setState({
        opacity: opacity      });
    }.bind(this), 100);
  },

  render: function () {
    return (
      <div style={{opacity: this.state.opacity}}>
        Hello {this.props.name}
      </div>
    );
  }});ReactDOM.render(
  <Hello name="world"/>,
  document.body);

上面代码在hello组件加载以后,通过 componentDidMount 方法设置一个定时器,每隔100毫秒,就重新设置组件的透明度,从而引发重新渲染。这里需要注意的地方是在setInterval的第一个参数也就是计时器触发函数后使用了bind(this),计时器函数中不能直接使用this来获取react的状态或属性,需要绑定this。

小结:

react提供的属性:

getInitialState 设置默认状态

setState 修改状态

render 返回组件

componentWillMount()    插入真实DOM之前调用

componentDidMount()    插入真实DOM之后调用

componentWillUpdate(object nextProps, object nextState) 重新渲染之前调用

componentDidUpdate(object prevProps, object prevState) 重新渲染之后调用

componentWillUnmount() 移出真实DOM之前调用

propTypes  验证组件实例的属性是否符合要求

getDefaultProps 设置组件属性的默认值。

最后两个属性本文中没有介绍,详细介绍请参阅http://www.ruanyifeng.com/blog/2015/03/react.html

你可能感兴趣的:(js,react,node)