{JS} React 快速实战Sat Sep 16 2017

React 是 Fackbook出品的一款专注于视图组件化的Javascript框架,其开发模式已经革新目前整个前端界的开发思维.



快速上手

在上手React之前必须先了解ES6的写法,因为React 15.x之后的版本一些API已经被拆分出来。 所以官方推荐是使用ES6的写法

第一个例子:

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

class Hello extends Component {
    render(){
        return (
            <h1>Hello Wolrd</h1>
        );
    }
}

ReactDOM.render(
    <Hello /> ,
    document.getElementById("app")
);

效果

react

React 和 ReactDOM 有所不同,其中React为主要核心库,而ReactDOM则是一些通用的方法

React 中包含了一些常用的继承模型, 如 Component, PureComponent, PropTypes 等

ReactDOM 则是一些与实例相关的方法, 如 render, unmountComponentAtNode, findDOMNode



JSX语法

可以看作是一种JavaScript 模版点写法,JSX语法比较灵活,可以嵌套JavaScript表达式.

JSX 中做了几个如下规定.

  1. 变量值必须用 { } 包裹

  2. { } 包裹的解析表达式 必须有返回值

  3. JSX中的HTML和组件都必须有终止符,例如这样的写法 <input id="id">, 自闭和标签input在HTML5语法中是完全正确的,但是在JSX语法中,这是错的, 必须写成 <input id="id" />

  4. 组件类型(继承于Component或者PureComponent)的组件采用首字母大写的形式,例如 <MyComponent />

  5. 标签属性只能解析大部分标准属, 例如name,id. 特殊的自定义属性(如:myattr, asd等随意命名的)虽然不会导致组件报错,但是在console中会被警告

  6. 基于 { } 需要返回值,所以在JSX中,没有if-else这样的判断语句,可以二元表达式代替, 如:{ person ? "Hello" : "GoodBye" }

  7. JSX组件必须且只能有一个父级元素, 例如 return (<h1>1</h1><h2>2</h2>) 是错误的,必须有一个父元素将它们包裹起来, 写成 return (<div> <h1>1</h1> <h2>2</h2> </div>), 才可以正确解析

  8. JSX不一定只写在render函数中,可以写在任意位置,任意函数中

  9. JSX中禁止使用JavaScript关键字, 例如在HTML中 <input class="myinput"> 没有任何问题,但是由于class是JavaScript的关键字, 所以在JSX中,class需要写成className, 如 <input className="myinput" />



状态和属性 ( State and Props )

State(状态)描述的是组件内部私有的可变属性,

Props(属性)则是描述组件不可变的属性(组件自身无法修改的属性, 从外部传入时获得)。

在React中,通过setState的方法可以改变组件的state值

例如我们编写一个计时器例子:

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

class Counter extends Component {
    constructor(props){
        super(props);

        this.state = {
            time : 0
        };
    }

    componentDidMount(){
        setInterval(()=>{
            this.setState({
                time: this.state.time+1
            });
        },1000);
    }

    render(){
        return (
            <div id={this.props.id} className="timer">
                {this.state.time}
            </div>
        );
    }
}

ReactDOM.render(
    <Counter id="time" />,
    document.getElementById("app")
);

效果

react

Props 属性是从外部传递到组件的

State 是组件内部自身的状态, 通过setState改变

组件内部Props的值是无法修改的,可以当作是const值来对待. 或者复制一份出来再进行修改



关于setState

需要理解的几个要点

setState 是异步的,更新机制 setState 是将状态放入到更新队列中(updateQueue), 然后合并更新之后将多个setState合并成一个提高效率. 详细可以看看 setTimeout(func,0) 的作用

setState 的更新是merge现有的状态,而不是全部覆盖, 例如组件本身的状态是 { a: 1 }, 进行更新 this.setState({ b: 2 }), 则该组件的状态就更新成了 { a:1 , b:2 }

理解children

React的任何一个组件都默认自带了一个属性. 叫做children, 通过this.props.children来获得.

通过 props.children 直接渲染可以做到动态的 子元素个数,由包裹的子元素个数决定,产生动态渲染。

在一些高级类型的组件里都会用,另外,可以给传入的children 批量写入需要的属性(props). 这是非常方便的

我们来看一个例子

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

class List extends Component {
    constructor(props){
        super(props);
    }

    render(){
        return (
            <ul>
                {this.props.children}
            </ul>
        );
    }
}

ReactDOM.render(
    <List>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </List>,
    document.getElementById("app")
);

效果

react

List 组件中无论传入多少个li元素都会被渲染出来

可以通过 React.Children.map 来为子元素li批量添加属性



后续

由于篇幅有限, React 快速上手,看到这里已经可以写基本的React组件了。

接下来应该通读官方的全局英文文档,React Document

更快速的了解React的组件的编写方式,以及一些基本的技巧。