React转小程序现状

React转小程序现状

2018/09/05 · JavaScript
· React,
小程序

初稿出处: 司徒正美   

至今做React转小程序,贰个是taro,一个是anujs。

anujs的React小程序一开首是群的正面搞的,后来神烦IT狗接手。当我们想抄袭时,已经有3个方可运作的demo。taro那时名气很大,但实质并不如意。小编钻探了好久taro的源码,发现可以行使tempate成分避开小程序的自定义组件不可以在构造器传参的难题,就规范开工了。

小程序的自定义组件不只怕在构造器传参的问题,
用过React的校友都知情,React的零部件构造器有三个传参props与context,那都是react帮您传入的。props是JSX中同名的竹签的性质组成的靶子,context是上边组件的getChildContext()爆发的目的的并集。而小程序的Component只是二个格局,你传什么它就有啥样,不会帮您加东西。

付出了大体上有多少个礼拜,已经脱离方正大大的源码。组件的思绪使用双模板机制——即用户编写时是React风格编写的(es6与jsx),通过大家一番神操作,它会生出多个公文,第多个是js文件,es5与createElement风格,类机制改由ReactWX的miniCreateClass方法落成,第三个是json配置对象,涉及路由的title与窗口颜色的定义,第两个是wxml文件,大家将render方法的jsx抽取出来,变成那个文件。

现行大家的React小程序有如下优势

  1. 支持npm安装
  2. 支持less与sass
  3. 协助小程序的自带UI库
  4. 支撑在JSX直接使用p, div, i,
    b等HTML标签,它们会在wxml转换到view与text标签。
  5. 支撑在JSX中行使函数体与复杂的对象传参,即onClick={function(){ console.log() }}onClick={this.changeAge.bind(this, index, {aaa:111,bbb: 222})}
  6. 协理React完整的生命周期,并保管顺序。
  7. 对wx全部接口举行再一次包新,将回调风格转换来Promise风格

美高梅开户网址 1

anu的React转小程序的习性是有保障的,它不会mpvue或taro那样使用nextTick,而是在多个页面的虚拟DOM更新完才发五次setData。那样就防止了复杂data
diff与data 连串化。

小程序的setData品质很差,不或者传入过大的对象,它会对data进行系列化。
因而一些转译框架会进展diff操作。但若是减缓它setData的频率,这一步就足以略去。

美高梅开户网址 2

事件系统上,匡助onXXX与catchXXX。catchXXX是模仿阻止事件冒泡已毕的API。微信小程序的同窗说,用户事件是异步的,所以那边唯有定义式接口,没有进程式的

美高梅开户网址 3

美高梅开户网址 4

与React的差异

1.
微信小程序的风浪机制有弱点,不辅助stopPropagation与preventDefault。大家将e.detail当成事件指标,在它基础上添加type,target,touches,timeStamp等品质与空的stopPropagation与preventDefault方法
2.
轩然大波的绑定,不要采用this.props.fn或this.state.fn,要用this.fn那种样式,微信在给模板填数据时,会对数据开展JSON.stringify,清掉全部事件。
3.
组件系统是基于小程序的template成分,由于不支持slot,由此不能使用{this.props.children}完结显式的组件套嵌

  1. 不完全协助ref机制(refs可以放入组件实例,但不恐怕放DOM,因为从没DOM)
  2. 无状态组件还不曾落到实处
    6 还尚未帮忙findDOMNode
  3. 不支持render props
  4. 不支持dangerouslySetInnerHTML属性

有关组件标签套组件标签,必要合法的slot机制协助,近期拿到的还原是这么的:

美高梅开户网址 5

JSX是React的大旨组成部分,它利用XML标记的点子去一向声明界面,界面组件之间可以相互嵌套。可以精通为在JS中编辑与XML类似的言语,一种概念带属性树结构(DOM结构)的语法,它的目标不是要在浏览器依旧引擎中落到实处,它的目标是因此各类编译器将那些标记编译成标准的JS语言。

1.React 的求学财富

  • react官方首页
    https://facebook.github.io/react/

  • react中文
    http://reactjs.cn/react/index.html

  • React Gitbook 翻译
    https://hulufei.gitbooks.io/react-tutorial/content/introduction.html

  • react普通话导航
    http://nav.react-china.org/

  • jsx首页
    https://facebook.github.io/jsx/

  • react教程
    http://www.runoob.com/react/react-tutorial.html

  • 方今各大集团的利用情形
    https://github.com/facebook/react/wiki/Sites-Using-React

  1. react 基本概念解析
  2. react 的零件申明周期
  3. react 高阶组件,context, redux 等高级进阶

使用

从“RubyLouvre/anu下”
git clone下来, 命令行定义到packages/cli目录下,执行npm link
动用mpreact <project-name> 创制工程
稳定到 <project-name> 目录下 mpreact start 开首监听文件变化,
用微信开发工具打开当中的dist目录,自个儿收在src目录中展开开发.

小程序在它的体量照旧1mb时,开发体验是很好的,品质也很好。但随着容积的界定松手了,产品经营发轫乱搞,小程序原生的API与组件机制就跟不上了。不容许3个APP上有13个弹层,每二个都写五次啊。缺少继承是它的硬伤。事件机制与大家耳熟能详的建制差太远。createSelectQuery也筹划得越发弱智,wxs过于奇怪。因而有了webview标签后,许三人直接引入页面了。。。因而才有那般转译框架的诞生,包蕴TX内部的weby。

当前市面上许多转译框架是vue风格的,那对React技术栈的同室不公道,于是有了taro与anu的转译器。anu保留了虚拟DOM的模板,由此会比taro,mpvue更能突破小程序的桎棝。

1 赞 收藏
评论

美高梅开户网址 6

即使你可以完全不应用JSX语法,只利用JS语法,但要么引进使用JSX,可以定义包涵属性的树状结构的语法,类似HTML标签这样的行使,而且更利于代码的翻阅。

2.React

什么是React?

  • React 是多少个用以打造用户界面的 JAVASC君越IPT 库。
  • React紧要用于打造UI,很多少人觉得 React 是 MVC 中的 V(视图)。
  • React 起点于 脸谱 的内部项目,用来架设 非死不可 的网站,并于
    二〇一二 年 5 月开源。
  • React
    拥有较高的属性,代码逻辑卓殊简单,更多的人已初阶关心和利用它。
  • 既可以支付浏览器采取,又可以付出移动应用

React 特点

  • 1.声明式设计 −React拔取注解范式,能够轻松描述应用。
  • React转小程序现状。2.高效 −React通过对DOM的效仿,最大限度地压缩与DOM的交互。
  • 3.心灵手巧 −React可以与已知的库或框架很好地包容。
  • 4.JSX − JSX 是 JavaScript 语法的扩张。React 开发不必然使用 JSX
    ,但大家提议使用它。
  • 5.组件 − 通过 React
    打造组件,使得代码尤其便于得到复用,可以很好的行使在大类型的费用中。
  • 6.单向响应的数量流 − React
    落成了一派响应的数据流,从而裁减了双重代码,那也是它干吗比古板数码绑定更简便易行。

什么是JSX?
React 使用 JSX(JavaScript XML) 来代替常规的 JavaScript。JSX
是1个看起来很像 XML 的 JavaScript 语法扩充。大家不需求自然使用
JSX,但它有以下优点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
  • 它是项目安全的,在编译进程中就能发现错误。
  • 使用 JSX 编写模板尤其简明便捷。

行使JSX语法后,你不可以不要引入babel的JSX解析器,把JSX转化成JS语法,这么些工作会由babel自动落成。同时引入babel后,你就可以使用新的es6语法,babel会帮您把es6语法转化成es5语法,包容越多的浏览器。

3.React的HelloWorld

开拓网址:https://facebook.github.io/react/docs/installation.html
官网中有啥样搭建React的Helloworld。
index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://unpkg.com/react@latest/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@latest/dist/react-dom.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    <script type="text/babel" src="01.js"></script>

</head>
<body>
<div id="root"></div>

</body>
</html>

01.js:

//React组件化(可以重用),即自定义组件
class TextCompat extends React.Component{
    //组件的内容
    render(){
        return <div>Hello world!!!</div>
    }
}


class WrapperText extends React.Component{
    render(){
        //虚拟DOM(Document Object Model)
        //html标签,小写开头
        //自定义组件:大写开头
        return <p>
            <TextCompat></TextCompat>
            jarry
        </p>
    }
}


//绘制到页面中
//ReactDOM.render(<WrapperText></WrapperText>, document.body);
ReactDOM.render(<TextCompat/>, document.getElementById('root'));

流程:
1.编制组件
2.绘制到页面

ReactDOM.render(<TextCompat/>, document.getElementById('root'));

虚拟DOM
DOM:html标签
编造DOM即包涵DOM又嵌套组件,和一般性DOM的分别:html标签是小写,组件是大写开头
虚拟DOM的好处:

  • 1.跨平台(讲虚拟DOM翻译成对应平台的言语)
  • 2.组件化管理,适合大型项目

缺点:

专程指示:

大家从最简便的一个官网例子helloworld先河:

4.React的状态

State(状态)
React 把组件看成是二个状态机(State
Machines)。通过与用户的互动,完毕差别景色,然后渲染
UI,让用户界面和数据保持一致。
React 里,只需立异组件的 state,然后按照新的 state
重新渲染用户界面(不要操作 DOM)。
不必要间接操作DOM,而是经过改动state,自动更新界面

1.开始化状态
2.改成状态
3.拿走状态,当状态改变的时候,会重绘页面

在意需要安装React dev tools的插件,来查看错误日志
须求用React.createClass,而不是用屡次三番的艺术,因为那一个会走生命周期流程。

案例:
点击切换,喜欢不欣赏?

//实例化组件对象过程中,调用getInitialState设置state对象的初始值
var Text = React.createClass({
    //设置状态的初始值
    getInitialState : function(){
        return {isLike:false};
    },
    //点击事件回调
    handleClick : function(){
        //改变状态
        this.setState({isLike:!this.state.isLike});
    },
    //当状态改变时,会重新调用render函数,重绘
    render : function(){
        //获取状态
        var text = this.state.isLike ? "喜欢" : "不喜欢";
        return <p onClick={this.handleClick}>你{text}吗?</p>
    }
});

ReactDOM.render(<Text/>, document.getElementById("myDiv"));

地点例子的加载流程:
1.getInitialState(先河化,设置组件的state的值,给了3个目的)
2.render(不喜欢)

点击之后的流水线
1.handleClick(点击回调)
2.setState(改变状态)
3.render(喜欢)

  1. 新本子更新
    React.createClass({ ….. }) 为es5 的写法,新版已经被丢掉
    class { ….. } 为 es6 的写法,推荐使用

  2. create-react-app 工程为自发性成立新 react
    工程的工具项目,该工具包蕴了打包、 测试、sourceMap、等成效。

  3. react 使用全家桶( react 项目中不可或缺的工具美高梅开户网址 , )
    React 在支付/生产 阶段须要一大堆的工具库支持开发
    编译:babel
    情状管理工具:redux
    单页应用:react-route

  4. dangerouslySetInnerHTML 用于安装不受爱抚的HTML
    <div dangerouslySetInnerHTML = {{ __html:
    this.state.不受爱抚的代码片段 }}></div>

  5. 好的 React 命名习惯

    • 自定义的机件使用 首字母大写的驼峰命名 (eg:
      InputComponent….. )
    • 自定义的性能使用 小驼峰命名 ( eg: this.state.getDate….. )
    • 事件尽只怕以 handle… 初始命名 (eg: handleChange….)
    • 组件私有的自定方法以下划线 _….. 先河命名 (eg:
      _getLocalDate…… )
  6. react 概念大全
    事件系统 + 表单应用 + 样式处理 + 组件通信 + 组件抽象 +
    组件质量优化 + 动画 + 自动化测试

  <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8" />
      <title>Hello React!</title>
      <script src="vendor-js/react.js"></script>
      <script src="vendor-js/react-dom.js"></script>
      <script src="vendor-js/babel-core/browser.min.js"></script>
    </head>
    <body>
      <div id="example"></div>
      <script type="text/babel">
        ReactDOM.render(
          <h1>Hello, world!</h1>,
          document.getElementById('example')
        );
      </script>
    </body>
  </html>

5.Props(属性)

state 和 props 紧要的界别在于 props 是不可变的,而 state
可以按照与用户交互来改变。那就是干吗某个容器组件要求定义 state
来更新和改动数据。 而子组件只能够通过 props 来传递数据。
能够通过 getDefaultProps() 方法为 props 设置私自认同值

var Text = React.createClass({
    render : function(){
        return <p>I love {this.props.name}</p>;
    }
});

ReactDOM.render(<Text name="Jason"/>, document.getElementById("myDiv"));

案例:
兑以往输入框中,输入内容,下面的文字控件也随着变动

//子组件
var TextComponent = React.createClass({
    render : function(){
        return <div>Hello {this.props.text}!</div>;
    }

});

//父组件
var WrapperComponent = React.createClass({
    //state初始化
    getInitialState : function(){
        return {text:''};
    },
    //内容改变回调
    handleChange : function(e){
        //e 是Event事件对象,target是指事件的目标对象
        //改变状态
        this.setState({text:e.target.value});
    },
    render : function(){
        return <div>
            <TextComponent text={this.state.text}/>
            <input type="text" onChange={this.handleChange}/>
        </div>;
    }

});

ReactDOM.render(<WrapperComponent/>, document.getElementById("myDiv"));

事例中传参流程
1.handleChange(父组件回调)
2.setState(修改父组件的动静)
3.render(父组件重新渲染,子组件也会渲染)
3.把父组件的境况值,作为子组件的属性值传入
4.render(子组件内容改动)

一:react 基本概念解析

  1. react 描述 DOM 的 方式 (JSX)jsx 其实就是 JavaScript 对象
  • 在 javascript 中运用类似于 HTML 结构和音信的语法为 JSX 语法。

    很容易转换编译成为 于 HTML 信息的 JavaScript 表示形式( `HTML 的 对象形式` )。
    
    可以根据平台 编译成为 第三方页面 UI 结构
    

美高梅开户网址 7

jsx编译进度.png

  • ReactDOM 解析
    ReactDOM 是 react 提供的 WEB 页面营造对, 在 移动端 该目的是
    ReactApp
    ReactDom 有八个办法:
    findDomNode( this ) // 用于获取页面中的DOM 元素
    UnmountComponentAtNode()
    render() // 用于页面渲染

  • ref 和 findDomNode 获取页面成分辨析
    ref 添加到 Component 上取得的是 Component 实例,
    ref 添加在 原生的 HTML 上得到的是 DOM 节点

        findDomNode 当参数是 DOM 时 就返回一个 DOM( 貌似没什么用 )
        findDomNode 当参数是 Component 时返回 Component 中的 render 中的 DOM
    
        <div>
            <div ref={div => {
                  this._div = div
                 }}>app
            </div>
            <Child ref={child => this._child = child}/>
            <button onClick={()=> {
                        console.log(ReactDOM.findDOMNode(this._div) === this._div);
                        console.log(ReactDOM.findDOMNode(this._child));
                 }}>log refs
            </button>
        </div>
    

    特点

    1. react 使用 jsx 描述 DOM / UI 结构
    2. jsx 预防在编译阶段 会转换为 DOM 的 JavaScript 表现形式
    3. ReactDom 对象只有3个效率 —> 负责将 JavaScript 对象
      渲染成为 真正的页面 DOM
    4. 在渲染进程中 react-dom( web ) ,react-canvas( canvas )
      ,react-app (react-native) 可各自将该 JS 对象渲染到不一致的平台上
  1. render 函数中都可以写什么

render 函数能且不得不 重回贰个 jsx 对象, 就是必须 重返三个值,并且这些值
是二个 类似于 DOM 的 jsx 语法

  • jsx 结构中能够利用 { } ( 大括号 ) 插入 表达式

    { } 大括号中 可以停舍弃何说明式内容( 包罗 函数,jsx
    结构,变量,对象,表明计算式 )

      ...
      render () {
          const isGoodWord = true
          return (
                      <div>
                            React 小书
                            {
                                // jsx 中的注释 只能写在 大括号中
                                // 下面表示一个三目表达式
                                // 这里不能写 JavaScript 的 多行表达式
                                isGoodWord ? <strong> is good</strong> :  is not good 
                            }
                            {
                                  // 下面表示一个自执行函数,函数中可以做任何你想做的事,也可以有多行代码
                                 (function() {
                                           .... doSomething
                                 })
                            }
                      </div>
                  )
      }
      ...
    
  • jsx 结构中的 null
    表示什么都不突显,约等于忽略了该表明式的插入,可以行使那个特性来 隐藏元素

  • jsx 结构全体当做变量用于 参数传递或然利用

    jsx 语法其实就是2个个 js
    的目的,所以可以运用其他变量能使用的措施传送或然应用它们

     ...
      render () {
          const isGoodWord = true
          const goodWord = <strong> is good</strong>    // 这是一个 jsx 变量
          const badWord =  is not good   // jsx 变量还可以当做 函数参数传递
          return (
              <div>
                    React 小书
                    {isGoodWord ? goodWord : badWord}
              </div>
         )
      }
      ...
    
  • 在 render 的 {} 中 可以使用 map 等 返回 DOM LIST 的函数方法

      // 必须返回一个 表示 DOM LIST 
     const arr = [1, 2, 3, 4, 5];
     render () {
          return (
                <select>
                      this.arr.map((item) => 
                          <option>item</option>
                      )
                </select>
            )
      }
      ...
    
  • jsx 中的 安慕希表达式 其实就是一句完整的表明式,所以可以被 识别

  1. jsx 语法中 注释的写法

    诠释只好写在 JavaScript 表达体 中( 即只能 写在 { } 大括号中
    ),写在 大括号外面的诠释不被辨认
    如果实在想写注释,可以给某些可能某条语句外面添加一个大括号,然后在开展诠释

  2. 零件嵌套

零件和组件之间可以 嵌套使用。不过富有的自定义组件都必须是以
大写字母起先的机件。

  1. 事件系统

    • 各类 jsx 成分上面都得以协调定义 on*
      类型的风浪监听函数,只好用在平时的 html
      元素标签上,不大概应用在自定义的因素标签上

    • 各样事件监听函数 都有贰个专断认同的 event
      对象。一个经过 react 包装的 event 对象

    • react 的轩然大波代理体制
      react 将事件处理函数统一绑定在最外层上面
      react 对于原生的 DOM 节点可以挥洒原生的轩然大波
      ** 尤其注意 **:
      因为 react 的事件代理机制,注意 stopPropagation() 阻止事件冒泡的时机

    • 只顾 每种 事件监听函数 若内部有应用到 this
      的情事,要求在表明函数的地点,动态的绑定 this

      // bind this 的时候 可以 传递默认的 参数
      render () {
          return (
              <h1 onClick={this.handleClickOnTitle.bind(this, 'Hello')}>React 小书</h1>
          )
      }
      
    • react 的 this 自动绑定区域
      A. class 内部自行绑定 this (
      class 的 { } 大括号这一层级 自动绑定 this )
      B. 构造函数 constructor 中并未自动绑定this
      C. 箭头函数自动绑定this
      D. 使用 bind 突显绑定 this

  2. state 的 使用

    • 老是调用 setState 都会触发 react 的再一次渲染,并且重新调用 render
      方法 **
  • setState 函数执行时方可接受1个参数(prevState)
  • 七个 setState 执行需求统近日 要求 prevState 参数的增援。并且
    react 会将 多个 setState 操作合并为一个最终的状态进行一次性渲染
  • react 自身的 diff 算法保证只会渲染更改的地方
  1. props 的使用
  • props 带来更好的复用性和 可配置性

  • defaultProps设置组件暗中认同的 props, 和 this.props 获取配置参数,设定
    组件的默许 props 数据

  • 零件内部一旦传递进 props 不可以在组件内部更改 props
    但是 组件内部 可以博得 props. 将其给予 state 大概其余变量进行数量的增删改。

在那么些大致的事例中,看不出来有其余jsx语法的地点,当其中<h1>Hello,world</h1>不怕利用到了jsx语法。HTML
语言直接写在 JavaScript 语言之中,不加任何引号,那就是 JSX
的语法,它同意 HTML 与 JavaScript 的混写。尽管转化成纯JavaScript
的话,就是:

6.React零部件生命周期

实例化

第一回实例化

  • getDefaultProps
  • getInitialState
  • componentWillMount
  • render
  • componentDidMount

实例化落成后的翻新

  • getInitialState
  • componentWillMount
  • render
  • componentDidMount

存在期
零件已存在时的景况改变

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

销毁&清理期

  • componentWillUnmount

零件的生命周期


  1. 前端的事态数据管理, – 状态升高

将零件之间共享的数据抽象并领取出来放到目前的 公共父节点上,然后通过
props 将数据传递给子组件, 那样就是二个意况数据的升官。

那么难题来了? 怎么样管理 三个层次的组件 所依靠的景况呢 ?
( ** 请我们关切 context 和 redux 的相关内容 ** )

  1. 组件的基础生命周期

美高梅开户网址 8

零件申明周期进度.png

react 将零件渲染 并塞到 DOM 成分中然后绘画在页面上的经过称为组件的挂载

为此 由挂载的进程你可以很好的了然上面的机件处理进程

constructor() // 伊始化状态数据
component威尔Mount() // 组件的挂载进度
render()
// 构造 DOM 成分 插入页面
componentDidMount() // 组件的挂载进度
。。。。。
// 即将从页面中去除成分
componentWillUnmount()
// 从页面中删去成分

上述 的多少个生命周期 皆以 组件的 第一阶段的状态管理函数

  • 一般的 getDefaultProps 和 getInitialState 都会放在 constructor
    中达成
  • 组件的隐藏 会触发 页面的 component威尔Unmount()
    函数,所以,在页面被隐形时要专注剩余数据 的拍卖。
  • component威尔Mount() 函数多用来组件的启航,eg: ajax,
    localStore数据的拉取,定时器的起步,等工作。
  • componentDidMount() 函数用于看重 DOM 的事件动作或然别的。eg:
    动画的运转需求借助 DOM. component威尔Mount 的时候 DOM
    还没有挂载达成,所以动画的开行须求放在 DidMount 函数中已毕
  1. 组件更新的生命周期

    shouldComponentUpdate(nextProps, nextState)
    返回一个 boolean 数据。 用于决定组件是还是不是 重新渲染。
    component威尔ReceiveProps(nextProps). 多用来拍卖父组件传递过来的
    props
    componentWillUpdate(); 组件伊始更新以前调用。
    componentDidUpdate(); 组件更新还要重新渲染到 DOM 之后调用。

  2. ref 的作用

ref 属性用于获取已经挂载的 DOM 节点(
类似于为元素添加 id 属性,用于表示元素 )
refs 用于引用已经 标识的 DOM 节点,获取其 对象的 属性 和 方法

** 注意: **
多余 的 DOM 操作 会产生代码的噪音,不推荐大量使用 ref 操作 DOM

ref 版本更改:标识 DOM 节点的 ref由原来的字符串改为三个回调函数
旧版本 <input ref=”myinput” />
新版本 <input ref={(input)=>{this.myinput=input;}}/>
可以额外有一个参数 参数有妙用

  1. props.children 和 自定义标签成分中 添加 额外的 HTML DOM 成分

一般说来的竹签成分中内嵌的 DOM
成分可以直接抬高。可是自定义标签组件怎讲将内嵌的 DOM
内容传递到下一层呢?

我们使用 props.children 可以获取到上层的 自定义标签中的内嵌的 DOM 元素

  1. jsx 中其余的 html 格式的 代码都会被转义掉,为了防患 xss 攻击

    为了突显 带有 html 标签的因素我们需求用到成分的
    dangerouslySetInnerHTML (
    这个只是元素的一个属性

    .....
    render() {
          renturn (
             <div
                    className="edit-html"
                     // 按照下面的方法设置元素的 html 的内容
                    dangerouslySetInnerHtml={ { __html: this.state.content } }
             >
        ) 
    }
    .....
    
  2. propsTypes 和 组件的参数验证
    JavaScript 是弱类型的语言,不过为了 **
    避免和校验上一层传递过来数据的不易,大家利用 PropTypes
    来做数据类型的校验相当于为数据添加数据类型,强类型的数据 **

     import React, { Component, PropTypes } from 'react'
     ....
     class ChildComponent extends Component {
           // 下面这些是固定的 书写格式
           static propsTypes = {
                 parentAttr: PropTypes. object,
                 parentArr: PropTypes.array
           }
           .........
     }
     ......
    
  3. 高阶组件就是1个函数,你传递给她2个组件对象,他归来给您三个通过包装的机件对象
    ** 约等于在原来组件之上 添加了一层经过包装的父组件 **
    功能性的封装

    ** 作用:**

    • 零件状态提高
      将子组件需求操作的多寡交由父组件来保管,然后通过 props
      向下传递数据。此为 状态提升
      当某些数据/状态 被三个零件看重/使用 时,应该经过情景提高来治本

    • 高阶组件本质就是为了组件之间的复用,将重新的代码
      操作放在高阶组件中,上边的为主组件就足以复用了

       比如数据的 ajax 的读取,事件的统一操作等
      
    • 高阶组件中 通过 props 传递数据

    • 高阶组件可以很好的落实 Smart 组件( 依赖数据操作的零部件/ 高阶组件
      ) 和 Dumb 组件( 只须要上层数据props的纯组件 ) 的分别

      Smart 组件和 Dumb 组件( 或者说高阶组件 )的出现,很好的实现了 react 的 mvc 结构,达到了高层次的 组件的复用。

高阶组件知识点

  1. 高阶组件 本质就是一种 组件的 mixin 方式
  2. es7 的点缀着方式可以用来增添高阶组件
  3. 三个 斯马特 组件可以被多个高阶组件装饰,并且依据顺序执行

美高梅开户网址 9

高阶组件.png

  1. react 的 context 作为全局的靶子,有协调特有的写法

    ** context 必须和 propType 强制数据类型 共同采用 **

    • 强制数据类型
      import React, { Component, PropTypes } from ‘react’
      ……
      static propsTypes = {
      themeColor: PropTypes. string
      }

    • 定义context 时的写法

      import React, { Component, PropTypes } from 'react'
      ....
      class ParentComponent extends Component {
          // 下面这些是固定的 书写格式
          static propsTypes = {
                themeColor: PropTypes. string
          }
          .........
          // 这里设置了 本组件包括其 所有子组件的 context 
          getChildContext () {
                 return { themeColor: this.state.themeColor }
          }
      }
      ......
      

    context 在概念时,必须有七个步骤
    扬言属性的数据类型
    设置获取全局 Context 的法门 getChildContext

    • 使用 context

            import React, { Component, PropTypes } from 'react'
            ....
            class ChildComponent extends Component {
                  static propsTypes = {
                        themeColor: PropTypes. string
                   }
                  render () {
                          return (
                                <div  style={{ color: this.context.themeColor }}>context 的获取使用地方</div>
                          )
                   }
            }
      

    context 在采取时务必有多少个步骤
    声称要动用的 context 数据类型
    使用 this.context.属性 获取属性的值

context 使用手续繁杂是有来头的

  1. context 作为全局具有的靶子,必须确保其数量的不利。
  2. react 官方不引进应用 context, 进而希望大家可以运用进一步和谐的
    Redux, Mobx等
    <script type="text/javascript">
      ReactDOM.render(
        React.DOM.h1(null,'hello,world!'),
        document.getElementById('example')
      );
    </script>

7.生命周期共提供了11个不等的API。

1.getDefaultProps
效益于组件类,只调用两遍,重返对象用于安装暗中认可的props,对于引用值,会在实例中共享。

2.getInitialState
职能于组件的实例,在实例创制时调用四次,用于初步化每种实例的state,此时可以访问this.props。

3.componentWillMount
在形成第四回渲染从前调用,此时还是能修改组件的state。

4.render
必选的不二法门,创制虚拟DOM,该方式具有非同平日的平整:

  • 只可以经过this.props和this.state访问数据
  • 可以回来null、false或任何React组件
  • 只好出现一个一等组件(不大概回来数组)
  • 无法更改组件的情形
  • 无法改改DOM的出口

5.componentDidMount
真实的DOM被渲染出来后调用,在该办法中可经过this.getDOMNode()访问到实在的DOM成分。此时已足以采纳任何类库来操作那么些DOM。
在服务端中,该方式不会被调用。

6.componentWillReceiveProps
组件接收到新的props时调用,并将其作为参数nextProps使用,此时得以变更组件props及state。

    componentWillReceiveProps: function(nextProps) {
        if (nextProps.bool) {
            this.setState({
                bool: true
            });
        }
    }

7.shouldComponentUpdate
组件是还是不是相应渲染新的props或state,重临false表示跳过三番五次的生命周期方法,平常不须求接纳防止止现身bug。在出现应用的瓶颈时,可因此该格局开展适量的优化。
在首次渲染时期还是调用了forceUpdate方法后,该方法不会被调用

8.componentWillUpdate
吸纳到新的props可能state后,举行渲染此前调用,此时不容许更新props或state。

9.componentDidUpdate
姣好渲染新的props或许state后调用,此时可以访问到新的DOM成分。

10.componentWillUnmount
零件被移除在此以前被调用,可以用来做一些清理工作,在componentDidMount方法中加上的具有职分都亟待在该方式中打消,比如成立的定时器或丰盛的风云监听器。

React 组件进阶


  1. react 理念分析

    • React 的零部件本质是创办了贰个对象,由框架本人添加了 拾二个注明周期函数(
      其实就是普通的函数,只是有执行顺序、触发时机、优化处理等特点
      )
      切实参见 React 的初期写法 React.createClass({ …. }),
      中间是3个对象

    • 宣称周期函数,就是目的中的普通函数
      传值 + 操作处理 + 重临值

    • react 特点:

      1. 简短: 丰硕的简要,其本人唯有协调的 api
      2. 非讲明式的单项数据绑定
      3. ** 面向 HTML5, 专注视图层操作 ** 将 JavaScript 和 HTML5
        整合在一块。
      4. 高质量的密集 DOM 操作
      5. 协助后端渲染。
      6. 跨平台,一种书写,可以编译出八种结果 ** ReactNative **

      react 函数式编程 ( 小函数编程 )

      1. 尽或许抽象出国有使用的小函数。
      2. 在八个混乱的 逻辑体 中可以提取出 功用小函数
    • 组件化
      狭义的组件化:ui组件 —> 具体的零件( Tabs 组件 / Dropdown
      组件 )
      广义的组件化: 业务数据 + UI 组件的三结合使用

      组件化的前进进度

      DOM操作为主( 根据逻辑改变 DOM 结构 ) –>
      MVC( 数据和界面解耦 ) –>
      小组件( 数据 + 界面 + 样式的结合体 eg: angular 指令 ) —->
      HTML5 的引入 ( javascript + HTML + css 合为一体)

      HTML Templetes –> custom Element –> shadow DOM –>
      HTML Imports

    • ** 非凡重大:**
      ** 组件封装的进度实际就是面向对象的想想逐步成熟**
      通过实例化的方法制造对象

      二个零件的目的实例: ( 基本的封装性 + 简单的表明周期 +
      明显的数据流动 )

  2. 表单组件

    表单组件分为受控组件和非受控组件
    受控组件:依靠 state 和其中事件
    改变状态的零件,有很强的耦合性,复用性不高

       非受控组件,通过 defaultProps, props 传值的组件,复用性好
               非受控组件可以通过 事件和 ref 向上传递数据
    
  3. 零件通信 —> 事件订阅
    EventEmitter

  4. 零件品质优化

    1. 引入纯函数( pureRender 函数或然 斯马特组件 )

    2. 动用 数据相比较决定 纯函数零部件是不是渲染 shouldComponentUpdate()

    3. 引入不可变对象 可能 es6 对象增添 进行数据相比较

         Immutable 不可变对象,对 Immutable 对象的 增 删 改 都会生成一个新对象,类似于对象的深拷贝,但是比对象的深拷贝效率要高
      
         es6 对象扩展 和 对象/数组的解构赋值,也能够得到一个新的对象
      
    4. Immutable 解析

      ** Immutable 可以提供一种全新的数额相比较和变化方式,类似于 es6
      的目的扩展 和 解构赋值 **

         Immutable 三种数据类型 
         Map: 对应于 `Object`, 键值对集合
         List :   对应于 `Array` 有序的重复列表
         ArrayList: 无序不可重复的列表
      
         // 特性应用实例
         import { Map, List, Arraylist } from 'immutable'
         ....
         this.setSatate({
                 data: Map({ times: 0 })      // 得到一个新的 Immutable 对象
         })
      

      Immutable 方法应用实例 ( Immutable.is 可以用来进展相比,比 ===
      全等的频率高 )

         import { is } from 'immutable'
         .....
         shouldComponentUpdate(nextProps, nextState) {
               if( is( nextProps.attr, nextState.attr ) )
                     return false;
              ......
         }
      

.

在上述JSX语法中有两个要注意的地点:

8.传参

因而品质Props可以在父组件中给子组件设置属性值,相当于将父组件的值传递给子组件。不过要消除子组件访问父组件的主意,可以透过回调函数化解,那就和Java的接口一样。
她的基本点思路:子组件委托父组件处理。

下边通过2个案例来已毕

  • 下拉列表(子组件)的数额发生变动,表单(父组件)可以获取到,用于末端的提交子组件向父组件传递参数

1.下拉摘取组件:

//表单的子组件
var ChildGenderSelect = React.createClass({
    render : function(){
        return <select onChange={this.props.handleSelectChange}>
            <option value="1">男</option>
            <option value="0">女</option>
        </select>;
    }
});

2.表单的机件:

//提交数据的两种做法:
//1.直接提交表单,跳转,整个页面刷新(过时的做法)
//2.屏蔽表单的默认提交行为,通过ajax提交数据,服务器响应成功之后在跳转(类似于Android)
var ParentForm = React.createClass({
    getInitialState : function(){
        return {gender:0};
    },
    handleChange : function(e){
        //保存到state
        this.setState({gender:e.target.value});
    },
    handleSubmit : function(e){
        //屏蔽表单的默认提交行为
        e.preventDefault();
        //ajax发起请求,提交数据
        /*var request = new XMLHttpRequest();
        request.open("GET","test.json?gender="+this.state.gender);
        request.onreadystatechange = handler;
        request.responseType = "json"; //服务器响应数据的类型 json
        request.setRequestHeader("Accept","application/json");
        request.send();

        //回调
        function handler(){
            //4(完成)响应内容解析完成
            if(this.readyState !== 4){
                return;
            }
            if(this.status == 200){
                //请求成功:显示数据
                console.log("ok");
            }
        }*/
    },
    render : function () {
        return <form onSubmit={this.handleSubmit}>
            <ChildGenderSelect handleSelectChange={this.handleChange}></ChildGenderSelect><br/>
            <button type="submit">提交</button>
        </form>;
    }
});

3.将表单组件渲染到页面:

ReactDOM.render(<ParentForm></ParentForm>,document.body);

4.案例的流水线:
(1).通过handleSelectChange属性,传入父组件的handleChange函数给子组件。
(2).当子组件的onChange事件触发,调用this.props.handleSelectChange->父组件的handleChange函数。

  • <script> 标签的 type 属性为 text/babel,那是React 独有的 JSX
    语法,跟 JavaScript 不包容。凡是在页面中间接接纳 JSX
    的地点,都要加上 type=”text/babel”。
  • 总括用了多少个库: react.js 、react-dom.js 和 browser.min.js
    ,它们必须首先加载。其中,react.js 是 React 的宗旨库,react-dom.js
    是提供与 DOM 相关的作用, browser.min.js的效能是将 JSX 语法转为
    JavaScript 语法。

9.表单提交和函数复用

案例:

  • 点击提交按钮,提交输入框输入的始末,通过Ajax请求提交

1.办法一:不可控组件
一言九鼎思路:通过ref获取组件

var FormComponent = React.createClass({
    //处理表单提交
    handleSubmit : function(e){
        e.preventDefault();
        //ref类似于id,是一个唯一标示 React.findDOMNode
        var text = this.refs.input_name.value;
        alert(text);
    },
    render : function(){
        return <form onSubmit={this.handleSubmit}>
            <input type="text" ref="input_name" defaultValue="Hello..."/><br/>
            <button type="submit">提交</button>
        </form>;
    }
});

ReactDOM.render(<FormComponent></FormComponent>,document.body);

2.方法二:可控组件(和MVVM data binding很接近)
首要思路:把多少存储在情景中(通过事件监听,举行数据绑定),必要时,从气象中获取

var FormComponent = React.createClass({
    getInitialState : function () {
        return {text:''};
    },
    handleChange : function(e){
        //保存到state
        this.setState({text:e.target.value});
    },
    handleSubmit : function(e){
        e.preventDefault();
        alert(this.state.text);
    },
    render : function(){
        return <form onSubmit={this.handleSubmit}>
            <input type="text" defaultValue="Hello..." onChange={this.handleChange}/><br/>
            <button type="submit">提交</button>
        </form>;
    }
});

ReactDOM.render(<FormComponent></FormComponent>,document.body);

进而暴发的标题:五个控件须求多个事件处理函数,如何成功事件处理函数的复用?

3.办法三:事件处理函数的复用格局1
在形式二的根基上进行校对,让子控件可以完毕复用,并保存对应的属性值。
思路:bind重临改变了内外文this后的函数

var FormComponent = React.createClass({
    getInitialState : function () {
        return {
            username:'',
            gender:0,
            agree:true
        };
    },
    //key ->'username' ....
    handleChange : function(key,e){
        //this->FormComponent对象
        //保存到state
        var obj = {};
        obj[key] = e.target.value;
        this.setState(obj);
    },
    handleSubmit : function(e){
        e.preventDefault();
        console.log(this.state);
    },
    //多个控件的事件响应,共用这个函数
    render : function() {
        return <form onSubmit={this.handleSubmit}>
            <label htmlFor="username">输入用户名:</label>
            <input id="username" type="text" onChange={this.handleChange.bind(this,'username')}/><br/>
            <label htmlFor="gender">请选择性别:</label>
            <select id="gender" onChange={this.handleChange.bind(this,'gender')}>
                <option value="1">男</option>
                <option value="0">女</option>
            </select><br/>
            <label htmlFor="agree">是否同意:</label>
            <input id="agree" type="checkbox" onChange={this.handleChange.bind(this,'agree')} /><br/>
            <button type="submit">提交</button>
        </form>;
    }

});

ReactDOM.render(<FormComponent></FormComponent>,document.body);

只顾:this的效率域难点,即使this内定的函数是非箭头函数,会招致功能域不正确,子控件拿不到相应的函数和属性值。

4.办法四:事件处理函数的复用格局2
思路:内定属性,比如说name属性区分差其余零件

var FormComponent = React.createClass({
    getInitialState : function () {
        return {
            username:'',
            gender:0,
            agree:true
        };
    },

    handleChange : function(e){
        var obj = {};
        obj[e.target.name] = e.target.value;
        this.setState(obj);
    },
    handleSubmit : function(e){
        e.preventDefault();
        console.log(this.state);
    },
    //多个控件的事件响应,共用这个函数
    render : function() {
        return <form onSubmit={this.handleSubmit}>
            <label htmlFor="username">输入用户名:</label>
            <input id="username" type="text" name="username" onChange={this.handleChange}/><br/>
            <label htmlFor="gender">请选择性别:</label>
            <select id="gender" name="gender" onChange={this.handleChange}>
                <option value="1">男</option>
                <option value="0">女</option>
            </select><br/>
            <label htmlFor="agree">是否同意:</label>
            <input id="agree" name="agree" type="checkbox" onChange={this.handleChange} /><br/>
            <button type="submit">提交</button>
        </form>;
    }

});

ReactDOM.render(<FormComponent></FormComponent>,document.body);

将 JSX 语法转为 JavaScript
语法,这一步很开销时间。以后前端项目,都会拔取前端工程化,不会直接在html页面中间接写js代码,写好的js代码都会利用工具举办编译压缩等。那样的话,我们的jsx也会因而编译间接转账成js语法,让浏览器直接行使。

10.动画

案例:让二个文字,在3秒之类从左到右移动一段距离
思路:用定时器,不断更改属性值,并渲染。

var MyComponent = React.createClass({
    getDefaultProps : function(){
        return {
            position:100, //marginLeft目标值,组件实现可配置
            time:10
        };
    },
    getInitialState : function () {
        return {position:0};  //marginLeft开始值
    },
    render : function(){
        var style = {
            color:'red',
            marginLeft:this.state.position //左外边距
        };
        return <div style={style}>This will animated!</div>;
    },
    //动画函数,不断改变state的position属性
    transformComponnent : function () {
        if(this.state.position < this.props.position){
            this.setState({
                position : ++this.state.position
            });
        }else{
            //动画完成,取消定时器
            clearInterval(this.timer);
        }
        console.log("transformComponnent");
    },
    //渲染完成
    componentDidMount : function () {
        //开启定时器
        this.timer = setInterval(this.transformComponnent,this.props.time);
    }
});


ReactDOM.render(<MyComponent position={200} time={20}></MyComponent>,document.body);

流程
1.开端化控件,执行生命周期中的getDefaultProps 和getInitialState ;
2.控件渲染达成,执行componentDidMount ;
3.拉开定时器,不断推行transformComponnent ;
4.保留意况setState;
5.不断渲染render,渲染的时候marginLeft拿取状态值;

ReactDOM.render 是 React 的最主题办法,将模板转为HTML语言,并插入钦赐的
DOM 节点。

11.计时器案例

1.模块化
把一部分类,函数,变量写到3个文书中,作为贰个功效模块,当要采纳那几个模块,只需求引用。
nodejs不匡助,用Bable6转es6为es5(js库,已毕模块化),es6模块化(新的语法个性),node和chrome都不资助。

2.创建react工程
支撑语法脾气,十分便于

npm install -g create-react-app
create-reate-app test
cd test

3.模块引入和导出
开创贰个组件
class TimeDisplay extends React.Component{
}

引入:import React form ‘react’;

导出:export default TimeDisplay;

4.代码

this唯有在运作时才规定
转为箭头函数,因为this的效用域是最外层的,比普通的function少了绑定this步骤;
在构造函数中对事态赋起首值,不可能调用setState
TimeDisplay.js:

import React from 'react';

import DisplayLog from './DisplayLog';
import Button from './Button';
import formatTime from '../utils/formatTime';

class TimeDisplay extends React.Component{
    //在构造函数中对状态赋初始值
    constructor(props){
        super(props);
        //不能调用state
        this.state = {
            time:0,
            on:false,
            log:[] //数组
        };
    }

    //开始按钮
    handleToggle = ()=>{
        //已经开始,取消正在运行的定时器
        if(this.state.on){
            clearInterval(this.timer);
        }else{
            //否则开启
            //定时器,10ms累加1
            this.timer = setInterval(()=>this.setState({time:this.state.time+1}),10);
        }
        this.setState({on:!this.state.on});
    }
    //记录时间
    handleLogTime = ()=>{
        //存储在数组中
        this.state.log.push(this.state.time);
    }
    //清空记录
    handleClearLog = ()=>{
        this.setState({log:[]});
    }
    //重置
    handleReset = () =>{
        this.setState({time:0});
    }

    render(){
        var time = formatTime(this.state.time);
        return <div>
            <h1 className="display-time">{time}</h1>
            <div className="controls">
                <Button className={this.state.on ? "danger" : "success"} text={this.state.on ? "暂停" : "开始"} onClick={this.handleToggle}/>
                <Button className="warning"  onClick={this.handleReset}/>
                <Button className="primary" text="记录" onClick={this.handleLogTime}/>
                <Button className="undefined" text="清空" onClick={this.handleClearLog}/>
            </div>
            <DisplayLog log={this.state.log}/>
        </div>;
    }

    //监听键盘事件
    componentDidMount(){
        //内置对象
        window.addEventListener('keydown', e => e.preventDefault());
        window.addEventListener('keyup', e => {
            e.preventDefault();
            switch (e.keyCode){
                case 32: //space
                    this.handleToggle();
                    break;
                case 82:
                    this.handleReset();
                    break;
                case 13:
                    this.handleLogTime();
                    break;
                case 67:
                    this.handleClearLog();
                    break;
                default:
                    break;
            }
        });
    }

    //组件被移除,事件监听取消
    componentWillUnmount(){
        window.removeEventListener('keydown');
        window.removeEventListener('keyup');
    }

}

//在外部要使用TimeDisplay
export default TimeDisplay;

Button.js:
button的包裹,数据、样式、事件的传递

import React from 'react';

class Button extends React.Component{
    //静态属性,给属性赋默认值
    static defaultProps = {
        onClick : null,
        className : '',
        text : '默认'
    };

    render(){
        return <button className={`Button ${this.props.className}`} onClick={this.props.onClick}>{this.props.text}</button>;
    }
}

export default Button;

DisplayLog.js:

import React from 'react';
import formatTime from '../utils/formatTime';

class DisplayLog extends React.Component{
    //log数组长度等于0,返回“空空如也”
    renderEmpty = () =>{
        return 空空如也...;
    }

    //否则,把元素遍历(时间),得到一系列的<li>
    renderLog = () => {
        //<li>00</li>
        //<li>11</li>
        return this.props.log.map(item => {
            return <li className="log-item" >{formatTime(item)}</li>;
        });
    }

    render(){
        //log数组长度等于0,返回“空空如也”
        //否则,把元素遍历(时间),得到一系列的<li>
        //<ul>
        //  <li>00</li>
        //  <li></li>
        //</ul>
        const log = this.props.log.length === 0 ? this.renderEmpty() : this.renderLog();
        return <ul className="log">
            {log}
        </ul>;
    }
}

export default DisplayLog;

formatTime.js:

//将数组转为字符串,如果数字只有一位,会在第一个位置添加一个0
//9->9->09
const appendZero = n => n.toLocaleString({},{minimumIntegerDigits:2});

export default function(t = 0){
    const msec = appendZero(t % 100),
        sec = appendZero(parseInt((t/100) % 60)),
        min = appendZero(parseInt((t/6000) % 60)),
        hour = appendZero(parseInt(t/360000));
    return `${hour}:${min}:${sec}.${msec}`;
}

App.css

.App {
  text-align: center;
}

ul,li{
  list-style: none; /*去掉列表默认样式*/
  margin: 0px;
  padding: 0px;
}

.display-time{
  font-size: 45px;
  font-weight: bold;
  margin: 60px 0px;
}

.controls{
  background-color: #eee;
}

.Button{
  width: 130px;
  font-size: 20px;
  padding: 10px 20px;
  margin: 20px;
  border: none;
  border-radius: 4px;
  background-color: lightgreen;
  cursor: pointer;
}

.Button:hover{
  /*CSS3阴影*/
  box-shadow: 0 0 25px rgba(0,0,0,0.2);
}

.success{
  background-color: lightgreen;
}
.danger{
  background-color: hotpink;
}
.warning{
  background-color: gold;
}
.primary{
  background-color: skyblue;
}
.undefined{
  background-color: #e1e1e1;
}

.log{
  text-align: center;
  font-size: 30px;
  color: #e1e1e1;
}

/*log和empty-log都会应用这个样式*/
.log .empty-log{
  display: inline-block;
  padding: 50px 10px;
}

/*.log类下的li标签 */
/*.log > li{*/
.log-item{
  font-size: 25px;
  color: #000;
  border-bottom: 1px solid #eee;
  padding: 10px 0px;
}

/*伪类*/
/*悬浮*/
.log-item:hover{
  background-color: rgba(238, 238, 238, 0.5);
}

App.js

import React from 'react';
import './App.css';
import TimeDisplay from './components/TimeDisplay'

class App extends React.Component {
  render() {
    return <div className="App">
      <TimeDisplay />
    </div>;
  }
}

export default App;

JSX的特点:

  1. 类XML语法简单接受,结构清晰
  2. 增强JS语义
  3. 架空程度高,屏蔽DOM操作,跨平台
  4. 代码模块化

12.常用的补充点

1.数组
数组的开创

var a = [];
var b = new Array();

数组的成分赋值

a[0] = 2;
a[1] = 10;
a.push(30);

清空

console.log(a);
a = [];
console.log(a);

map 遍历数组的函数

//item是数组的元素,i数组的索引,b是返回的数组
var b = a.map(function(item,i){
    return ++item;
});
console.log(b);

2.组件的二种成立方式
1.React.createClass
对应的质量和状态起始化方法:

getDefaultProps
getInitialState

2.extends Component
相应的习性和气象开首化方法:

static defaultProps
constructor

3.css样式
.log-item

JSX基本语法规则:

JSX本人就和XML语法类似,可以定义属性以及子成分。唯一特殊的是可以用大括号来出席JavaScript表达式。蒙受HTML 标签(以 < 早先),就用 HTML 规则解析;遭遇代码块(以 {
开端),就用 JavaScript 规则解析。

var arr = [
 <h1>Hello world!</h1>,
 <h2>React is awesome</h2>,
];
ReactDOM.render(
 <div>{arr}</div>,
 document.getElementById('example')
);

本条就是贰个简短的html与js混用的例证。arr变量中设有html成分,div中又利用了arr那一个js变量。转化成纯javascript的话:

var h1=React.DOM.h1(null,'Hello world!');
var h2=React.DOM.h1(null,'React is awesome');
var div=React.DOM.div(null,h1,h2);
ReactDOM.render(
 div,
 document.getElementById('example')
);

React组件

大家应用jsx来将代码封装成React组件,然后像插入普通 HTML
标签一样,在任啥地点方插入那些组件。使用React.createClass用于转移3个组件。

var MyComponent=React.createClass({
  render: function() {
   return <h1>Hello world!</h1>;
 }
});
ReactDOM.render(
 <MyComponent />,
 document.getElementById('example')
);

地点代码中,变量 MyComponent就是三个组件类。模板插入 <MyComponent
/> 时,会自动生成 MyComponent
的三个实例(下文的”组件”都指组件类的实例)。全体组件类都无法不有和好的
render 方法,用于出口组件。

React 能够渲染 HTML 标签 (strings) 或 React 组件 (classes)。

  • 在react中常见约定组件类的率先个字母必须大写,html标签都以小写。

//要渲染 HTML 标签,只需在 JSX 里使用小写字母初叶的标签名。
var myDivElement = <div className=”foo” />;
React.render(myDivElement, document.getElementById(‘example’));
//要渲染 React 组件,只需制造1个大写字母初始的本土变量。
var MyComponent = React.createClass({//});
var myElement = <MyComponent />;
React.render(myElement, document.getElementById(‘example’));

* 还有一个注意点:组件类只能包含一个顶层标签,否则会报错。
```javascript

//var myDivElement
=<h1>你好</h1><h1>hello</h1>;
//上述写法是会报错的,要写成只有3个顶层标签:
var myDivElement
=<div><h1>你好</h1><h1>hello</h1></div>;

上述代码2个静态的零件,上面看多少个动态组件:

var MyComponent=React.createClass({
  getInitialState: function() {
       return {clickNum: 0};
  },
  handleClick:function(){
    var num=this.state.clickNum;
    num++;
    this.setState({clickNum:num});
  },
  render: function() {
   return (
      <div>
        <h1 onClick={this.handleClick}>Hello {this.props.name}!</h1>
        <h2 style={{color:'red'}}>点击{this.props.name}次数:{this.state.clickNum}</h2>
      </div>
    );
 }
});
ReactDOM.render(
  <div>
     <MyComponent name="张三" />
     <hr/>
     <MyComponent name="李四" />
  </div>,
 document.getElementById('example')
);

地点代码中定义的MyComponent组件包含属性,状态和事件,是1个不难易行的可比完好的机件。使用props通过父组件举行传递值,使用state定义组件自个儿的图景,组件协助的大部分的DOM操作事件。

有关属性props:

  • class 属性要求写成 className ,for 属性须要写成 htmlFor ,那是因为
    class 和 for 是 JavaScript 的保留字。
  • 直接在标签上行使style属性时,要写成style={{}}是八个大括号,外层大括号是报告jsx那里是js语法,和实在DOM不相同的是,属性值不只怕是字符串而必须为目的,须求小心的是属性名同样要求驼峰命名法。即margin-top要写成marginTop。
  • this.props.children
    不要children作为把目标的属性名。因为this.props.children获取的该标签下的全数子标签。this.props.children
    的值有二种大概:假设当前组件没有子节点,它就是 undefined
    ;尽管有壹个子节点,数据类型是 object
    ;如若有两个子节点,数据类型就是 array 。所以,处理
    this.props.children
    的时候要小心。官方提议使用React.Children.map来遍历子节点,而不用担心数据类型。

至于状态state:

  • 组件免不了要与用户互动,React
    将零件看成是一个状态机,一初步有1个方始状态,然后用户互动,导致意况变化,从而触发重新渲染
    UI。
  • getInitialState
    方法用于定义起先状态,约等于1个对象,那些目的可以经过 this.state
    属性读取。当用户点击组件,导致情形变化,this.setState
    方法就修改景况值,每回修改之后,自动调用 this.render
    方法,再次渲染组件。

鉴于 this.props 和 this.state
都用来描述组件的特征,大概会生出模糊。一个不难易行的界别方法是,this.props
表示这几个一旦定义,就不再改变的特色,而 this.state
是会趁机用户互动而暴发变化的风味。

注意点:
如若往原生 HTML 成分里不胫而走 HTML 规范里不设有的本性,React
不会突显它们。尽管急需选取自定义属性,要加 data- 前缀。

<div data-custom-attribute=”foo” />

PropTypes

零件的质量props还行任意值,字符串、对象、函数等等都足以。有时,大家必要一种体制,验证外人利用组件时,提供的参数是还是不是符合须求。React中利用PropTypes进行参数的校验。

var MyTitle = React.createClass({
   propTypes: {
     title: React.PropTypes.string.isRequired,
   },
   render: function() {
     return <h1> {this.props.title} </h1>;
   }
});

地方的Mytitle组件有二个title属性。PropTypes 告诉 React,这几个 title
属性是必须的,而且它的值必须是字符串。当大家给title传递1个数字时,控制台就会报错:

Warning: Failed propType: Invalid prop `title` of type `number` supplied to `MyTitle`, expected `string`.

此外,getDefaultProps 方法可以用来安装组件属性的暗许值。

获取真实的DOM节点

零件并不是真心真意的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟
DOM (virtual DOM)。唯有当它插入文档未来,才会化为实际的 DOM 。
有时需求从组件获取真实 DOM 的节点,那时就要用到 ref 属性。

var MyComponent = React.createClass({
   handleClick: function() {
     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>
     );
   }
});

为了拿走真是DOM节点,html成分必须有一个 ref 属性,然后
this.refs.[refName] 就会回来那些实际的 DOM 节点。急需注意的是,由于
this.refs.[refName] 属性获取的是真性 DOM ,所以必须等到虚拟 DOM
插入文档将来,才能利用那脾特性,否则会报错。

求值表达式

要动用 JavaScript 表明式作为属性值,只需把那些表明式用一对大括号 ( { } )
包起来,不要用引号 ( ” ” )。
在编写JSX时,在 { }
中无法利用语句(if语句、for语句等等),但足以使用求值表达式,那作者与JSX没有多大关系,是JS中的特性,它是会重返值的表明式。大家不只怕间接行使语句,但足以把语句包裹在函数求值表达式中运用。

规格判断的写法

你没办法在JSX中选择 if-else 语句,因为 JSX
只是函数调用和目的创制的语法糖。在 { }
中运用,是不合规的JS代码,不过可以动用安慕希操作表明式

var HelloMessage = React.createClass({ 
  render: function() { 
    return <div>Hello {this.props.name ? this.props.name : "World"}</div>; 
  }
});
ReactDOM.render(<HelloMessage name="xiaowang" />, document.body);

可以利用相比运算符“ ||
”来书写,如果右边的值为真,则直接再次来到左侧的值,否则再次回到左侧的值,与if的法力同样。

var HelloMessage = React.createClass({ 
  render: function() { 
    return <div>Hello {this.props.name || "World"}</div>; 
  }
});
函数表明式

( )有强制运算的功效

var HelloMessage = React.createClass({ 
  render: function() { 
    return <div>Hello { 
    (function(obj){ 
        if(obj.props.name) 
          return obj.props.name 
        else 
          return "World" 
      }(this)) 
    }</div>; 
  }
});
ReactDOM.render(<HelloMessage name="xiaowang" />, document.body);

外括号“
)”放在外面和内部都可以实施。唯一的区分是括号放里面实践完成得到的是函数的引用,然后再调用“function(){}(this)()”;括号放在外边的时候拿到的事返回值。

零件的生命周期

零件的生命周期分成三个意况:

* 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):组件判断是否重新渲染时调用

注释

JSX 里添加注释很不难;它们只是 JS
表明式而已。你只须求在3个标签的子节点内(非最外层)小心地用 {}
包围要诠释的部分。

{/* 一般注释, 用 {} 包围 */}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图