本系列将尽可能使用ES6(ES2015)语法。所以均在上节webpack的基础上做开发。
React是Facebook开发的一款JS库,因为基于Virtual DOM,所以响应速度快,以及支持跨平台。 (实际上,Virtual DOM在某些情况都会损耗一些性能在diff上,但相比其他MVVM框架比起来性能影响很少,同时大幅提升开发效率也是目前推荐的方式)
安装
安装React: npm i -S react react-dom
安装Babel:npm i babel-loader babel-preset-react babel-plugin-import -S
HelloWorld
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
    <h1>Hello, world!</h1>,
    document.getElementById('root')
);
 
JSX
JavaScript 的一种扩展语法。我们推荐在 React 中使用这种语法来描述 UI 信息。
- JSX支持嵌入表达式:花括号 把任意的 JavaScript 表达式 嵌入到 JSX 中
 - JSX是Javascript:比起 HTML, JSX 更接近于 JavaScript, React DOM 使用驼峰(camelCase)属性命名约定。(html为全小写)
 - JSX防注入攻击:在渲染之前, React DOM 会格式化(escapes) JSX中的所有值。防止 XSS(跨站脚本) 攻击。
 - JSX编译后为: React.createElement()。
 
const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
 
const element = React.createElement(
  'h1',
  { className: 'greeting' },
  'Hello, world!'
);
 
// 注意: 以下示例是简化过的(不代表在 React 源码中是这样)
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world'
  }
};
 
组件
React框架的一大特色就是它通过组件化的方式来构建和渲染前端页面。 定义组件有很多方式,最主流的为:函数 和 类(类允许我们在其中添加本地状态(state)和生命周期钩子。)
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
 
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
 
Props
- 属性是只读的:无论你用函数或类的方法来声明组件, 它都无法修改其自身 props。
 - 属性是外部控制的:属性是由外部设置,组件内部是不确定属性从哪设置的。
 - 稳定性:对于同样的输入,始终可以得到相同的结果。
 
State
- state是内部控制的:state是私有的,并且由组件本身完全控制。
 - 使用setState修改: 
  
- 内部调用render
 - 支持异步
 - 支持更新合并state
 
 
生命周期事件
React组件的生命周期事件很多,常用的有:
- componentDidMount:在组件第一次初始化render方法后调用,此时组件(DOM及诶点)已创建完成。通常在此方法中ajax、使用第三方js框架。
 - shouldComponentUpdate:在组件接收到新的state或props后被调用。(第一次初始化和forceUpdate时不被调用。 )默认返回true,返回false的时候则不调用render方法。
 - componentWillUnmount:在组件从DOM中移除的时候被调用。通常用来移除组件相关事件。
 
生命周期事件又分为3条流程:
- 组件初始化(Mounting):getDefaultProps、getInitialState、componentWillMount、render、componentDidMount(getInitialState在ES6 class的构造函数中可直接对state初始化)
 - 组件props更新(Updating):componentWillReceiveProps(nextProps)、shouldComponentUpdate、componentWillUpdate、render componentDidUpdate
 - 组件卸载(Unmounting):componentWillUnmount
 
表单
受控组件
React负责渲染表单的组件仍然控制用户后续输入时所发生的变化。相应的,其值由React控制的输入表单元素称为“受控组件”。
class ShowInput extends Component {
    constructor(props) {
        super(props);
        this.state = {
            val: 'hello'
        }
    }
    onChange(e) {
        this.setState({
            val: e.target.value
        })
    }
    render() {
        return (
            <div>
                <input type="text" onChange={e => this.onChange(e)} />
                <div>{this.state.val}</div>
            </div>
        )
    }
}
 
DivInput组件中的input元素就是受控组件。value 和 onChnage都会由React控制。
非受控组件
    render() {
        return (
            <div>
                <input type="text" ref={e => this.input = e} />
                <button onClick={() => console.log(this.input.value)}>Click</button>
            </div>
        );
    }
 
挂到组件(这里组件指的是有状态组件)上的ref表示对组件实例的引用,而挂载到dom元素上时表示具体的dom元素节点。(stateless构造的组件是不会实例化,所以ref引用的为null)
ref属性可以设置为一个回调函数,这也是官方强烈推荐的用法;这个函数执行的时机为:
- 组件被挂载后:回调函数被立即执行,回调函数的参数为该组件的具体实例。
 - 组件被卸载或者原有的ref属性本身发生变化时:回调也会被立即执行,此时回调函数参数为null,以确保内存泄露。
 
ReactDOM.findDOMNode(ref)来获取组件挂载后真正的dom节点。
组件通信
组件之间通信的解决方案通常有2种:
- 状态提升:将state提升到互相通信组件的最近的一个父组件上
 - Redux:下节将介绍
 
来源:oschina
链接:https://my.oschina.net/u/4373953/blog/3286322