React

ReactJS的学习笔记

2016-08-01  本文已影响279人  void_main
ReactReact

React介绍

React只是一个view层的解决方案,它做的主要事情就是

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

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

props示意图props示意图

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

state示意图state示意图
能够引起state变化的动作有

JSX语法

很简单, 就是所有标签必须闭合. 比如像[站外图片上传中……(10)]这样的, 后面的/ 可以写可不写. 但是, 现在在JSX中,所有的都必须写.

// HTML
<input type="text" name="usrname" maxlength="10">

// JSX
<input type="text" name="usrname" maxLength="10"><br>

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

一旦你设置在input的value属性. 后面你所有的输入都是无效的.

<input type="search" value="React" />

这里就需要使用onChange和this.state来帮助我们进行重绘.

class Search extends Component {
    constructor(){
        super();
        this.state={
            value:"React"
        }
    }
    render() {
        return ( <div>
        Search Term: <input type="search" value={this.state.value} onChange={this.handleChange.bind(this)} /> </div>
        )
    }
    handleChange(event){
        this.setState({
            value:event.target.value
        })
    }
}

通过输入,触发onChange, 然后onChange 触发this.setState, 重新渲染DOM
JSX所有语法注意点总结如下

titletitle

JSX组件

JSX 组件分为 HTML 组件和 React 组件

关于Virtual DOM的理解

React的意思是,我提供一个Component,然后你只管给我数据,界面的事情完全不用你操心,我保证会把界面变成你想要的样子。
你可以把一个React的Component想象成一个Pure Function,只要你给的数据是[1, 2, 3],我保证显示的是[1, 2, 3]。没有什么删除一个Element,添加一个Element这样的事情。NO。你要我显示什么就给我一个完整的列表。

Virtual DOM和DOM是啥关系呢?
首先,Virtual DOM并没有完全实现DOM,Virtual DOM最主要的还是保留了Element之间的层次关系和一些基本属性。因为DOM实在是太复杂,一个空的Element都复杂得能让你崩溃,并且几乎所有内容我根本不关心好吗。所以Virtual DOM里每一个Element实际上只有几个属性,并且没有那么多乱七八糟的引用。所以哪怕是直接把Virtual DOM删了,根据新传进来的数据重新创建一个新的Virtual DOM出来都非常非常非常快。(每一个component的render函数就是在做这个事情,给新的virtual dom提供input)
所以,引入了Virtual DOM之后,React是这么干的:
你给我一个数据,我根据这个数据生成一个全新的Virtual DOM,然后跟我上一次生成的Virtual DOM去 diff,得到一个Patch,然后把这个Patch打到浏览器的DOM上去。完事。

最后,回到为什么Virtual Dom快这个问题上。
其实是由于每次生成virtual dom很快,diff生成patch也比较快,而在对DOM进行patch的时候,我能够根据Patch的内容,优化一部分DOM操作,比如之前1.2里的那个例子。
重点就在最后,哪怕是我生成了virtual dom,哪怕是我跑了diff,但是我根据patch简化了那些DOM操作省下来的时间依然很可观。所以总体上来说,还是比较快。
而更糟糕的是,我们(以及很多框架)在调用DOM的API的时候做得不好,导致整个过程更加的慢。React的Virtual Dom解决的是这一部分问题,它并不能解决DOM本身慢的问题。
比如说,现在你的list是这样,

<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>

你想把它变成这样

<ul>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>

通常的操作是什么?
先把0, 1,2,3这些Element删掉,然后加几个新的Element 6,7,8,9,10进去,这里面就有4次Element删除,5次Element添加。
而React会把这两个做一下Diff,然后发现其实不用删除0,1,2,3,而是可以直接改innerHTML,然后只需要添加一个Element(10)就行了,这样就是4次innerHTML操作加1个Element添加,比9次Element操作快多了吧?

作者:EMayej Bee
链接:http://www.zhihu.com/question/29504639/answer/44680878
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

Flux组件

Flux简介

Flux 的思维模型1Flux 的思维模型1
Flux 的思维模型2Flux 的思维模型2
其中 Dispatcher 是 Flux 的核心枢纽,它相当于是一个事件分发器,将那些分散在各个组件里面的逻辑代码收集起来,统一在 Dispatcher 中进行处理

完整的Flux处理流程如下

Flux优点

Flux 把所有的 View 都视作愚民,Store 视作资源的拥有者为统治者,统治者需要提供资源(数据)给平民,但是如果平民企图对资源修改(Mutation),必须得先通知给统治者,让统治者决定是否做处理。
我们为 Flux 中的概念分配角色

一个企图修改资源的操作可以描述为:
View Require Mutation -> Action -> Dispatcher -> Store -> Mutate Handler

平民提交 Mutation 请求,由审核官控制,审核通过后递交给统治者,统治者再分配给亲信做资源 Mutation
合而治之的策略也等于中心化控制策略, 作为统治者既要懂得放权利(资源的分配),也要懂得控制权利(资源的修改),这种收缩自如的合理性是 Flux 简洁的根本。
同时这种思维带来的优点如下:

Flux实例

学习flux的一些浅显理解
结合github上flux的flux-todomvc项目进行介绍

import AppDispatcher from '../dispatcher/AppDispatcher';
import TodoConstants from '../constants/TodoConstants';

var TodoActions = {
  create (text) {
    AppDispatcher.dispatch({
      actionType: TodoConstants.TODO_CREATE,
      text: text
    });
  },
  // other actions
}

export default TodoActions;

当我们执行 AppDispatcher.dispatch 这个方法,并传给他一个有 actionType 属性的对象时,他就会在大喊,“有人做了一个操作呀,这个操作就是 xxx (actionType 的值),还带了个参数,你们哪个来处理一下呀

var TodoActions = {

  /**
   * @param  {string} text
   */
  create: function(text) {
    AppDispatcher.dispatch({
      actionType: TodoConstants.TODO_CREATE,
      text: text
    });
  },

import AppDispatcher from '../dispatcher/AppDispatcher';
import TodoConstants from '../constants/TodoConstants';

AppDispatcher.register((action) => {
  var text;

  switch(action.actionType) {
    case TodoConstants.TODO_CREATE:
      text = action.text.trim();
      if (text !== '') {
        create(text);
        TodoStore.emitChange();
      }
      break;

    // other case
  }
});
import assign from 'object-assign';

var EventEmitter = require('events').EventEmitter;

var TodoStore = assign({}, EventEmitter.prototype, {
  areAllComplete () {
    for (var id in _todos) {
      if (!_todos[id].complete) {
        return false;
      }
    }
    return true;
  },
  getAll () {
    return _todos;
  },
  emitChange () {
    this.emit(CHANGE_EVENT);
  },
  addChangeListener (callback) {
    this.on(CHANGE_EVENT, callback);
  },
  removeChangeListener (callback) {
    this.removeListener(CHANGE_EVENT, callback);
  }
});

export default TodoStore;

Redux介绍

titletitle
redux 可以理解为基于 flux 和其他一些思想(Elm,函数式编程)发展出来的前端应用架构库,作为一个前端数据状态容器体现,并可以在 React 和其他任何前端框架中使用。
前端基本框架图前端基本框架图

Redux 就是用来确保 state 变化的可预测性,主要的约束有:

state 为单一对象,使得 Redux 只需要维护一棵状态树,服务端很容易初始化状态,易于服务器渲染。state 只能通过 dispatch(action) 来触发更新,更新逻辑由 reducer 来执行。

区别点 flux redux
store 多个store,在store中执行更新逻辑 只有一个 ,更新逻辑不再store中执行,而是放在reducer
dispatcher

React Reflux

Action、Store和组件这三者是通过事件机制响应变化的,构建组件的时候首先需要监听Store的状态。先定义Action和Store
React Reflux

╔═════════╗       ╔════════╗       ╔═════════════════╗
║ Actions ║──────>║ Stores ║──────>║ View Components ║
╚═════════╝       ╚════════╝       ╚═════════════════╝
     ^                                      │
     └──────────────────────────────────────┘
var TodoActions = Reflux.createActions([
    'addItem'
]);

var TodoStore = Reflux.createStore({
    items: [1, 2],
    listenables: [TodoActions],//store监听actions的行为
    onAddItem: function (model) {
        $.post('/server/add', {data: model}, function (data) {
            this.items.unshift(data);
            this.trigger(this.items);
        });
    }
});


var TodoComponent = React.createClass({
    mixins: [Reflux.listenTo(TodoStore, 'onStatusChange')],
    getInitialState: function () {
        return {list: []};
    },
    onStatusChange: function () {
        this.setState({list: TodoStore.items});
    },
    render: function () {
        return (
            <div>
                {this.state.list.map(function (item) {
                    return <p>{item}</p>
                })}
            </div>
        )
    }
});


React.render(<TodoComponent />, document.getElementById('container'));
区别点 flux reflux
store 多个store,在store中执行更新逻辑 stores可以监听actions的行为,无需进行冗杂的switch判断,stores可以监听actions的行为,无需进行冗杂的switch判断
dispatcher 通过内部拓展actions的行为,移除了单例的dispatcher

React

React/React Native 的ES5 ES6写法对照表

参考资料

精益 React 学习指南 (Lean React)序
精益 React 学习指南 (Lean React)- 1.1 React 介绍
最新版React入门
玩物圈前端技术栈总结(React+Redux)
Redux 中文文档
Redux 介绍
浅谈 React、Flux 与 Redux

上一篇下一篇

猜你喜欢

热点阅读