最新版React入门

工欲善其事必先利其器, 因为react崇尚的是, react一体化. 即, 使用js拯救世界. 所以, 我们需要先将支持react的webpack 工具解决.

webpack 配置

这里主要使用的是这些模块:

        "babel-loader": "^6.2.4",
        "babel-core": "^6.8.0",
        "babel-loader": "^6.2.4",
        "babel-plugin-transform-es2015-arrow-functions": "^6.8.0",
        "babel-preset-es2015": "^6.6.0",
        "react-dom": "^15.2.1",
        "react" : "^15.2.1"

将这些文件放到package.json中,然后使用npm install 即可.
这里就不赘述了. 先放一个最简单的webpack.config.js文件.

var path = require('path'),
    node_modules = path.resolve(__dirname, 'node_modules');

module.exports = {
    // context: __dirname + "/app/src/entry",
    entry: {
       app:"./dev/app"
    }, //演示单入口文件
    output: {
        path: path.join(__dirname, '/dev/dist'), //打包输出的路径
        filename: '[name].entry.js', //打包后的名字
    },
    module: {
        loaders: [{
                test: /\.js|\.jsx$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel?presets[]=es2015' //加载使用loader
            }
        ]
    },
    plugins: [
    ],
    watch: true
};

这里需要注意一下, 由于版本的问题, webpack 在v1.13之后, 会默认给entry文件添加extensions. 所以如果你的entry写成了,./dev/app.js的话, 恭喜你, 踩坑了. 如果万一出错了, 你可以使用

webpack --display-error-details

来进行排查. ok , 现在我们正式进入react时间

react 入门

初期, react基本的操作无外乎就是围绕着,Component和ReactDOM进行编写和渲染。 以前, react并没有分的太细化, 不过在version 0.14版本后, ReactDOM和Component就分开了, 主要还是因为React Native的缘由.
不过, 两者分开过后,造成的影响来说, 还是不小的. 主要影响到三个方面:

  • ReactDOM.render(): 渲染UI层

  • ReactDOM.findDOMNode(): 获取节点

  • ReactDOM.renderToString(): 后端运用的转义String方法

上面, 我们已经下载好了reactreact-dom. 我们可以来简单看一个demo:

import React,{Component} from 'react';
import ReactDOM from 'react-dom';

class Hello extends Component{
    render(){
        return (
        

Hello world

); } } ReactDOM.render(,document.getElementById('container'));

重要的是Hello 类中的render方法. 通过return, 返回虚拟的DOM, 然后经过ReactDOM将虚拟的DOM, 渲染到指定节点内部.

动态内容

假如我们现在想要在render中, 使用变量,so how to do?
很简单, 只要在DOM里面用到curly braces({})即可.

class Hello extends Component{
    render(){
        let name="jimmy";
        return (
        

Hello {name}

); } }

嵌套UI

React之所以这么流行,就是因为他的可复用性. 通过< classname /> 这样的调用, 就可以完美的实现, 组件的复用

class UI_item extends Component{
    render(){
        return (
                
    ); } } class UL extends Component{ render(){ return (
      ok yes
    ) } } class Li_item extends Component{ render(){ return (
  • my name is {this.props.name}   and my content is {this.props.children}
  • ) } }

    在进行组件复用时, 重用UI 和写HTML一样, 使用闭合标签,添加属性等等. 不过,这里需要注意一下, 在JSX语法中, class属性需要换成 className(因为内部冲突).
    另外, 提及一下上文出席那的两个内容. this.props.xx 和this.props.children

    • this.props.xxx : 是用来获得节点中的属性内容. 比如: name, data-name,data-set等等.

    • this.props.children: 用来获取闭合tag中的内容. 比如: < div>abc< /div> 获取得到为: abc

    this.props 在组件复用中,是占很重要的地位的, 可以说,他是parent和children 组件通信的重要通道, 父组件 赋值, 子组件处理. like:

    通常来说, 写一个整体的UI 有两种方式, 一种是Top-Down, 一种是Bottom-Up. 两者都行, 只是思考的方式不一样, 不过一般TD(自顶向下)方式比较普遍些.

    如果你想利用循环生成jsx的话, 可以使用:

    class UL extends Component{
        render(){
            let tasks = [];
            for(var i=1,len=this.props.number;i<=len;i++){
                tasks.push(
                    list
                    )
            }
            return (
                
      {tasks}
    ); } }

    但需要注意的是, 你不能直接写为:

    return (
        {tasks}
    )

    如果这样写的话,react是不会让你通过的. 因为他认为你这个是不合法数据, 一般来说, 不能在第一层里面直接写入: arrar,object 对象.

    状态改变

    react 提供另外一个状态属性-this.state. React 通过改变父组件本身的state, 会导致DOM的重新渲染, 相当于重新调用ReactDOM.render().

    have a try

    这里, 我们通过简单的改变, 父组件的state, 来实现节点的重流和重绘.
    实现的demo 放在jsFiddler上, 可以参考一下. 这里我只贴精华的demo:

    class UI_item extends Component{
        constructor(){
            super();
            this.state={
                origin:true
            }
        }
        render(){
            let number = 5;
            if(!this.state.origin){
                number*=2;
            }
            return (
                    
      ); } doubleNumber(){ this.setState({ origin:!this.state.origin }); } }

      上面的代码其实有点绕的. 这里补充几点, 相信看过之后,再回去看代码也就明白了.

      • this.setState({xxx:xxx}): 该方法是父组件的专属方法, 其可以手动的修改state的状态, 来实现状态的更新.

      • this.state: 初始情况下,是在constructor 方法中, 直接设置。 不过, 你也可以放在render 方法中, 这也是没问题的.

      • 事件绑定: React中绑定事件的代码虽然有点奇葩, 但他确实是绑定事件最简洁的办法. 他会在后面的流程中,自动解析事件内容, 然后使用addEventListener进行绑定.

      另外, 你新增this.props也是会重新渲染节点的.

      结合,上面的this.props 可以大概了解, React 提供的精华架构.

      最新版React入门_第1张图片

      事件绑定解析

      React 之所以高性能, 不仅在于虚拟DOM的算法, 事件绑定也在一定程度提升性能. 因为React的所有事件都是绑定在document 根元素上.
      比较好的绑定方式是,通过函数+bind方法进行绑定的

          render(){
              let number = 5;
              if(!this.state.origin){
                  number*=2;
              }
              return (
                      
        ); }

        来看一下,React 提供的事件.
        from pro react

        最新版React入门_第2张图片

        小心JSX的坑

        React 在提出本身的同时, 也提出了JSX语法. 这是为什么呢?
        我们可以看一下,React 是如何翻译JSX语法, 你就应该知道为什么JSX很受欢迎~

        // JSX
        

        Hello World

        // React 方法调用 React.createElement("h1", null, "Hello World");

        当你写出JSX 的时候,React在背后已经帮你解析成对应的方法了. 所以, 这样隐形的API, 为什么不用呢?
        不过JSX 中有部分内容需要注意一下.

        驼峰命名的属性

        在JSX中, 给tag添加属性时,需要使用驼峰命令. 即.

        // HTML
        
        
        // JSX
        

        但像,这样的data-set 使用dash连接的就不需要额外的注意. 另外, react 特别强调了class需要写为className. 因为在React内容,class 存在冲突, 所以强制性将class property改为了className.

        标签闭合

        很简单, 就是所有标签必须闭合. 比如像这样的, 后面的/ 可以写可不写. 但是, 现在在JSX中,所有的都必须写.

        only one node

        这里,应该是很多初入React 童鞋常常犯的~ 可能对函数的了解还未透彻. 比如一个函数:

        function add(){
            return (1,2);
        }
        add();

        上面的结果是多少?
        很简单是2. 这是解析引擎所决定的. 因为, 直接通过return 语句返回, 永远只能返回一个值.所以, 这也决定了在React中, 你使用render返回JSX时, 只能带上一个节点.

        // 正确
        return(
          

        Hello World

        ) // go die return (

        Hello World

        Have a nice day

        )

        改写一下, 你只能返回一个节点:

        return (
            

        Hello World

        Have a nice day

        )

        don't use if-else

        在JSX, 一般不要乱用if-else. 因为if-else 是不会返回任何值的。

        // 报错
        return (
                    
      • jimmy
      • )

        推荐情况是, 使用三元运算(ternary). 因为他可以返回值.

        return (
                    
      • jimmy
      • )

        置于为什么, 我们可以在这里剖析一下JSX语法的结构. 前文已经提到了, JSX其实就是React.createElement(). 我们的属性其实,就是当做createElment参数的

        // JSX
        
        Hello JSX
        // 翻译 React.createElement("div", {className: if (condition) { "salutation"}}, "Hello JSX");

        这里, 有点基本常识的应该知道, 对象里面怎么执行... 除非你有返回值.

        空格省略

        React在渲染的时候,会默认忽略掉元素间的空格. 估计是考虑到了inline-block 造成的3~4px的影响.

      • {this.props.children}_{this.props.number} ok yes
      • 这样渲染的结果是

        最新版React入门_第3张图片

        不过, 如果你仅仅是填写文本的话, 里面的空格就不会被忽略。如果, 你想在元素之间添加上空格的话. 可以这样写:

      • ok {" "} yes
      • JSX的评论

        在JSX中,写评论的话, 需要注意他的注释方式:

        /* comment */

        另外,如果你的注释是childElement, 则需要使用{}括起来. 但在元素内部评论的话,就不需要了

        上面的demo 基本上把所有注释情况都包含了.

        动态插入HTML

        以前,我们纯原始写组件的时候, 常常利用的就是element的innerHTML属性. 即, 直接在html tag里面添加string, 然后利用内部渲染,将element渲染出来.

      • {this.dynamicP()}
      • // 动态脚本 dynamicP(){ let p = "

        123

        "; return p; }

        但是, 这样容易犯的一个错误就是XSS, 因为XSS最常用的手段就是动态恶意脚本的插入. 有兴趣的童鞋,可以参考一下我的xss之网页安全.
        React考虑到这点, 果断将所有一切插入的String进行转义.
        所以, 上面渲染出来的会是这样的:

        p

        当有时候,我们又不得不使用动态的String当做HTML插入, 那应该怎么做呢?
        官方给出的解决办法是, 使用dangerouslySetInnerHTML这个属性.

        这样, React就会对插入的HTML解除XSS的限制.

        表单输入

        为什么说表单输入在React里面也是一块需要注意的呢?
        因为, 一旦你设置在input的value属性. 后面你所有的输入都是无效的.

        so how to solve it?
        这里就需要使用onChange和this.state来帮助我们进行重绘.

        class Search extends Component {
            constructor(){
                super();
                this.state={
                    value:"React"
                }
            }
            render() {
                return ( 
        Search Term:
        ) } handleChange(event){ this.setState({ value:event.target.value }) } }

        通过输入,触发onChange, 然后onChange 触发this.setState, 重新渲染DOM。get~ 线上demo

        另外,表单输入,还需要注意另外两个ele. textarea和select.

        textArea 在React中, textarea的书写格式和HTML中有些不同

        // HTML
        
        
        // React