Learning React

故知

背景

Web1.0

Web2.0

  • jQuery
  • Angular
  • React
  • Vue

React VS Vue

- Vue

- React

  • 上手容易
  • 对旧代码侵入小
  • 迅速释放生产力
  • 更加成熟
  • 更好的生态与社区
  • 系统性的思考与实践

准备知识

JSX

  • Facebook提出的语法扩展

  • 用类似HTML语法创建HTML元素

  • HTML元素内部,花括号中的JS表达式将被解析

准备知识

JSX

<div className='ui items'>
  <p>
    Hello, friend! I am a basic React component.
  </p>
</div>
React.createElement('div', {className: 'ui items'},
    React.createElement('p', null, 'Hello, friend! I am a basic React component.')
)

准备知识

JSX之道 —— 语法糖

  • Ruby —— 高糖

  • Java —— 低糖

  • JavaSript —— 无糖

准备知识

ES6 —— 面向未来的JS

Const & Let

const ProductList = React.createClass({ render: function () {
    return (
    <div className='ui items'>
        Hello, friend! I am a basic React component.
      </div>
    ); 
  },
});
let hello = "hello react";

块级作用域

准备知识

ES6 —— 面向未来的JS

import & class

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
class Timer extends React.Component {
    ...
}

 模块化

准备知识

ES6 —— 面向未来的JS

Function Literal 箭头函数

const timestamps = messages.map(function(m) { return m.timestamp });
const timestamps = messages.map(m => m.timestamp);

准备知识

Bable

  • javascript transpiler
  • 翻译成ES5标准的JS代码
<head>  
    <script src="vendor/babel-core-5.8.25.js"></script>
    
    <body>
        <script type="text/babel" src="./app-complete.js"></script>
    </body>
</head>

React基础

Component

可复用的组件

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

React基础

Component - Props

描述组件的不可变属性

class MyTitle extends React.Component {
  render() {
    return <h1 style={{color: this.props.color}}>
      Hello {this.props.message}
    </h1>;
  }
};

ReactDOM.render(
  <MyTitle color='red' message='world'/>,
  document.getElementById('mountNode')
);

React基础

Component - State

  • 内部状态 - 自我管理 

  • 外部状态 - 通过Props传入 

  • State 变化触发DOM更新

React基础

Component - State

React基础

Virtual DOM

  • 分层diff
  • 差异化更新
  • 批量渲染

React基础

Component - LifeCycle

React之道

Thinking In React

  • 以函数的方式思考组件,props作为输入,render element 作为输出

  • Function like water, it's better when pure

  • 纯组件,给定相同的输入,就一定会得到相同的输出

React之道

函数式编程的优势

  • 更好的组件化,更高的复用性

  • 更易理解,更易推理

  • 更易测试

  • 更适应于并发场景

React之道

单向数据流

  • 在父组件中管理公共状态

  • 禁止组件之间随意的相互通信 

  • 在计算机的世界,集权比民主更高效 

  • data pipeline, 基于数据流思考程序设计 

React进阶

七步创建React应用

Step 1 -- 将应用分解为组件

React进阶

七步创建React应用

Step 2 -- 创建静态版本的应用

class Timer extends React.Component {
  render() {
    ...
  }
}


export default Timer;

React进阶

七步创建React应用

Step 3 -- 确定哪些部分是有状态的

  • Timer列表与Timer的属性

  • 创建Timer窗口是否打开

  • 编辑Timer窗口是否打开 

React进阶

七步创建React应用

Step 4 -- 确定状态应该属于哪个组件

  • Timer列表与Timer的属性 -- TimersDashboard

  • 创建Timer窗口是否打开 -- EditableTimer

  • 编辑Timer窗口是否打开 -- ToggleableTimerForm

React进阶

七步创建React应用

Step 5 -- 硬编码初始化状态

class ToggleableTimerForm extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      "isOpen": false
    };
  }


  render() {
    if (this.state.isOpen) {
      return (
        <TimerForm />
      );
    } else {
      return (
        ...
    }
  }
}

export default ToggleableTimerForm;

React进阶

七步创建React应用

Step 6 -- 添加反向数据流

class ToggleableTimerForm extends React.Component {

  constructor(props) {
    super(props);
  }

  handleFormClose() {...}

  handleFormSubmit(timer) {...}

  render() {
    if (this.state.isOpen) {
      return (
        <TimerForm 
        onFormSubmit={this.handleFormSubmit.bind(this)}
        onFormClose={this.handleFormClose.bind(this)}/>
      );
    } else {
      ...
    }
  }
}

React进阶

七步创建React应用

Step 7 -- 添加后端数据通信

Text

  • NodeJS

  • Rails

  • SpringMVC

React Router

  • Hash方式

  • History API

React Router

核心组件

  • <Link>

  • <Redirect>

  • <Match>

  • <Miss>

React Router

单页应用(SPA)

Webpack -- 解析模块依赖图,打包生成bundle.js

var webpack = require('webpack');

module.exports = {
  devtool: debug ? "inline-sourcemap" : null,
  entry: "./js/scripts.js",
  output: {
    path: __dirname + "/js",
    filename: "scripts.min.js"
  },
  plugins: debug ? [] : [
    new webpack.optimize.DedupePlugin()
  ],
};

React Router

收益

更好的用户体验

Flux

一种设计模式

Text

  • 解耦用户操作与状态变化

  • 使父组件免于复杂的状态管理

Flux

一种设计模式

Text

Redux

名称解释

Store, Reducer, Dispacher

Redux

执行流程

Redux

代码实例

聊天室应用

Redux

Redux之道

  • 所有的状态数据由store统一管理

  • 应用从Store读取状态

  • 状态只在store内部被改变

  • 状态变迁通过reducer函数实现

  • reducer函数为纯函数

Redux

Redux之道

  • 设计模式,大象无形

  • 类似消息队列

Integration

基础形态 -- 在页面中嵌入component.js

  • 难以管理依赖

  • 性能无法接受

Integration

进化形态 -- 使用WebPack

  • 自动管理依赖

  • 编译打包bundle

  • Hot reloading/ Hot swapping

Integration

究极形态 -- 前后端分离

方案

学习路线

基础,基础,基础

  • HTML/CSS/JavaScript
  • jQuery

React

React Router, Flux, Redux

Tesing, GraphQL,  React Native,  Dva,  AntD

  • JSX
  • ES6
  • Npm/WebPack

学习资料

Bye Bye