React 学习笔记

一、初识React

  A Javascript Library For Building User Interfaces  

  React 是一个 UI 库,具体说 React 是做 UI 组件的 JavaScript 库,也就是用 JS 写前端UI。

  React是用来构建随着时间顺序数据在不断变化的大规模应用程序。

  每次的数据变化,页面也将自动更新,且只更新变化的那一部分。将显示数据变得简单。React不会去操作真正的DOM,用一种更快的内置仿造的DOM来操作差异,为你计算出效率更高的DOM改变。

  React实现了一套完整的事件合成机制,能够保持事件冒泡的一致性,跨浏览器执行。

  基于JSX脚本开发,通过提供的转换器可转换为JS。

  React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。React 来决定如何最高效地更新 DOM。


二、开发环境配置

  对于react,我们只关注两点。第一个就是,JSX的支持,另外一个就是,ES6的支持。

  好消息是业界领先的 ES6 编译工具 Babel 随着作者被 Facebook 招入麾下,已经内置了对 JSX 的支持,我们只需要配置 Babel 一个编译工具就可以了,配合 webpack 非常方便。

  安装 Webpack:npm install -g webpack(前提是已经安装好了node,利用node的npm安装)

  Webpack 使用一个名为 webpack.config.js 的配置文件,要编译 JSX,先安装对应的 loader: npm install babel-loader --save-dev

  假设我们在当前工程目录有一个入口文件 entry.js,React 组件放置在一个 components/ 目录下,组件被 entry.js 引用,要使用 entry.js,我们把这个文件指定输出到 dist/bundle.js,Webpack 配置如下:

  var path = require('path');
  module.exports = {   entry: './entry.js',   output: {    path: path.join(__dirname, '/dist'),    filename: 'bundle.js'    },    resolve: {    extensions: ['', '.js', '.jsx']   }, module: { loaders: [ { test: /\.js|jsx$/, loaders: ['babel'] }   ]    }   }

  resolve 指定可以被 import 的文件后缀。比如 Hello.jsx 这样的文件就可以直接用 import Hello from 'Hello' 引用。

  loaders 指定 babel-loader 编译后缀名为 .js 或者 .jsx 的文件,这样你就可以在这两种类型的文件中自由使用 JSX 和 ES6 了。

  监听编译: webpack -d --watch

  更多关于 Webpack 的介绍    webpack-howto

三、第一个Hello World组件

  var Hello = React.createClass({

    render:  function(){

      return <div>Hello {this.props.name} </div>

      }  

  })

  ReactDOM.render(<Hello name='World' />,

  document.getElementById('container'))

  页面将显示Hello World

四、JSX

  JSX是可选的,无需在react中必须使用。JSX类似于HTML的XML格式,可以通过函数调用来生成一个模版,将类XML的语法转换成原生的JS。

  i> 使用JSX:

     var Hello = React.createClass({

         render :  function() {

                    return <div>{this.props.name}</div>

                }

      })

        ReactDOM.render({<Hello name='John' /> , root})

       ii> 不使用JSX

           var Hello = React.createClass({

      render : function() {

       return React.createElement(

        'div',

          null,

        'Hello',

        this.props.name

       )

        }

    })

   ReactDOM.render(React.createElement(Hello,{ name: 'John'},root))

     可以通过React.createElement()来创建一个树,参数是1)标签名2)属性对象3)子节点

  可以通过 {变量名} 来将变量的值作为属性值  

  JSX熟悉扩散 JSX Spread Attributes 

  可以用通过 {...obj} 来批量设置一个对象的键值对到组件的属性,注意顺序,因为熟悉可以被覆盖

         var Hello = React.createClass({

    render:  function(){

      return <div>name:{this.props.name},age:{this.props.age}</div>

                }

     })

   var user = {'name': 'John','age': 13}

   ReactDOM.render(<Hello {...user} name='Andy' /> , document.body)

      页面将显示name:Andy,age:13,Andy覆盖了John

     组件(标签)需要闭合。

  组件的render函数只能返回一个根节点,如果包含多个子组件,需要使用div或者span或者其他组件包裹。

五、组件

  1)组件生命周期

    一个简单的例子(使用ES6语法)

    import {Component}, React  from 'react'

    import {render} from 'react-dom'

    class LikeButton extends Component {

      constructor(props) {

        super(props)

        this.state({like: false})

      }

    handleClick() {

      this.setState(like: !this.state.like)

    }

    render() {

      let text = this.state.like ? 'like' : 'unlike'

      return (

        <div>

          <button onClick = {this.handleClick.bind(this)}>

            {text}

          </button>

        </div>

        )

      }

    }

    render(<LinkeButton /> , root)

    组件的生命周期主要有三个部分:

    i>挂载:组件被注入DOM

    ii>更新:组件被重新渲染来决定DOM是否应该被更新

    iii>卸载:组件从DOM中移除

    每一个部分都有对应的生命周期函数

    i>挂载:

      componentWillMount()

      只会在挂载之前调用一次,在 render 之前调用,你可以在这个方法里面调用 setState 改变状态,并且不会导致额外调用一次 render

      componentDidMount()

      只会在挂载完成之后调用一次,在 render 之后调用,从这里开始可以通过ReactDOM.findDOMNode(this) 获取到组件的 DOM 节点。

    ii>更新:     

      这些方法不会在首次 render 组件的周期调用

      componentWillReceiveProps()

      shouldComponentUpdate()

      componentWillUpdate()

      componentDidUpdate()

    iii>卸载:

      componentWillUnmount()

   其它:

      getInitialState()  初始化 this.state 的值,只在组件挂载之前调用一次。

      如果是使用 ES6 的语法,你也可以在构造函数中初始化状态,比如:

      class Counter extends Component {        constructor(props) {       super(props);       this.state = { count: props.initialCount };        }        render() {       // ...        }      } 

       getDefaultProps()

       只在组件创建时调用一次并缓存返回的对象(即在 React.createClass 之后就会调用)。因为这个方法在实例初始化之前调用,所以在这个方法里面不能依赖 this 获取到这个组件的实例。在组件挂载之后,这个方法缓存的结果会用来保证访问 this.props 的属性时,当这个属性没有在父组件中传入(在这个组件的 JSX 属性里设置),也总是有值的。

                  如果是使用 ES6 语法,可以直接定义 defaultProps 这个类属性来替代,这样能更直观的知道 default props 是预先定义好的对象值:

            Counter.defaultProps = { initialCount: 0 };

     render()

      必须要添加的方法。组装生成这个组件的 HTML 结构(使用原生 HTML 标签或者子组件),也可以返回 null 或者 false,这时候 ReactDOM.findDOMNode(this) 会返回 null

  2) 事件处理

    从上一个生命周期的例子可得,可以看到 React 里面绑定事件的方式和在 HTML 中绑定事件类似,使用驼峰式命名指定要绑定的 onClick属性为组件定义的一个方法 {this.handleClick.bind(this)}。 

    注意要显式调用 bind(this) 将事件函数上下文绑定要组件实例上,这也是 React 推崇的原则:没有黑科技,尽量使用显式的容易理解的 JavaScript 代码。

    React 实现了一个“合成事件”层(synthetic event system),这个事件模型保证了和 W3C 标准保持一致,所以不用担心有什么诡异的用法,并且这个事件层消除了 IE 与 W3C 标准实现之间的兼容问题。

   “合成事件”还提供了额外的好处:

    “合成事件”会以事件委托(event delegation)的方式绑定到组件最上层,并且在组件卸载(unmount)的时候自动销毁绑定的事件。

  3)DOM操作

    在使用react时,我们不需要关心DOM怎样去更新UI,只是不断的更新state值,来渲染页面。但有时候,需要我们取到真实的DOM节点。

    当组件加载到页面上之后(mounted),你都可以通过 react-dom 提供的 findDOMNode() 方法拿到组件对应的 DOM 元素。

    componentDidMound() {
      const el = findDOMNode(this);
    }

    findDOMNode() 不能用在无状态组件上。
    另外一种方式就是通过在要引用的 DOM 元素上面设置一个 ref 属性指定一个名称,然后通过 this.refs.name 来访问对应的 DOM 元素。
如果 ref 是设置在原生 HTML 元素上,它拿到的就是 DOM 元素,如果设置在自定义组件上,它拿到的就是组件实例,这时候就需要通过 findDOMNode 来拿到组件的 DOM 元素。

  4)组件件通信

    父子组件间通信

    这种情况下很简单,就是通过 props 属性传递,在父组件给子组件设置 props,然后子组件就可以通过 props 访问到父组件的数据/方法,这样就搭建起了父子组件间通信的桥梁。

    import React, { Component } from 'react'
    import { render } from 'react-dom'
    class GroceryList extends Component {       handleClick(i) {       console.log('You clicked: ' + this.props.items[i])      }      render() {     return (      <div>     {this.props.items.map((item, i) => {       return (       <div onClick={this.handleClick.bind(this, i)} key={i}>{item}</div>        )      })}      </div>      )     }         }
  render(    <GroceryList items={['Apple', 'Banana', 'Cranberry']} />, mountNode   )

   div 可以看作一个子组件,指定它的 onClick 事件调用父组件的方法。

 

   

 

    

 

  

 

 

 

         

  

  

转载于:https://www.cnblogs.com/weitian/p/reactNote.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值