1、综合介绍
react整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入,所以在react中,是单向数据流,推崇结合immutable来实现数据不可变。react在setState之后会重新走渲染的流程,如果shouldComponentUpdate返回的是true,就继续渲染,如果返回了false,就不会重新渲染,PureComponent就是重写了shouldComponentUpdate,然后在里面作了props和state的浅层对比。
React具有声明式、异步、响应式的特性,使代码可预测,并让我们更有把握进行快速迭代。声明式编程范式(范式就是计算机程序架构与组件的构建风格),用这种范式表达计算逻辑时不需要描述控制流程。简单地说,声明式编程就是你编写代码描述想要做什么,而不是怎么做。
React的开发者采取了虚拟DOM的做法,虚拟DOM更加轻量,对真实DOM进行了抽象化,而且独立于特定浏览器的具体实现。每当触发需要改变DOM的事件时,React会创建一个新的虚拟DOM树,并将其与已有的树进行对比,计算出最少的DOM变化集合,把它们放入队列再全部批量执行,接着重新渲染视图。这种做法没有把重负荷操作全部加在真实DOM 上,因此比直接操作DOM快了很多。React的这种行为没有采用脏数据检查(dirty checking,持续检测模型变动),而是利用观察者模型进行变动检测,通过差分算法(diffing algorithm,http://calendar.perfplanet.com/2013/diff/)判断最少的DOM操作,因此很有效率。
React为可变命令式DOM接口编程提供了声明式封装。声明式的编程方法只需描述程序应该达成什么目的,而不用关心程序应该怎么运行。然而命令式编程需要逐步编写程序,将输入值计算成期望的输出。
- 开发简单,声明式编程:只需告诉React,你希望应用长成什么样。按照设计稿编写声明式视图,定义应用的状态。React会根据应用状态,仅更新、渲染对应的组件,非常高效。这让代码的编写和维护变得非常容易,同时更具可预测性,更容易调试。
- 组件化开发:Facebook宣称,“用了React,你只需要开发组件”。开发一整套组件,再把它们拼装成应用。
WebView是一个基于webkit引擎、展现web页面的控件。其作用为:
(1)显示和渲染Web页面
(2)直接使用html文件(网络上或本地assets中)作布局
(3)可和JavaScript交互调用
WebView控件功能强大,除了具有一般View的属性和设置外,还可以对url请求、页面加载、渲染、页面交互进行强大的处理。
React 并不是完整的 MVC/MVVM 框架,它专注于提供清晰、简洁的 View(视图)层解决方案。而又与模板引擎不同,React 不仅专注于解决 View 层的问题,又是一个包括 View 和 Controller 的库。对于复杂的应用,可以根据应用场景自行选择业务层框架,并根据需要搭配 Flux、Redux、GraphQL/Relay 来使用。
两种不同的元素:DOM 元素和组件元素。在 JSX 里自然会有对应,对应规则是 HTML 标签首字母是否为小写字母,其中小写首字母对应 DOM 元素,而组件元素自然对应大写首字母。
state 与 props 是 React 组件中最重要的概念。如果顶层组件初始化 props,那么 React 会向下遍历整棵组件树,重新尝试渲染所有相关的子组件。而 state 只关心每个组件自己内部的状态,这些状态只能在组件内改变。把组件看成一个函数,那么它接受了 props 作为参数,内部由 state 作为函数的内部参数,返回一个 Virtual DOM 的实现。
浏览器原生 DOM 事件的传播可以分为 3 个阶段:事件捕获阶段、目标对象本身的事件处理程序调用以及事件冒泡。事件捕获会优先调用结构树最外层的元素上绑定的事件监听器,然后依次向内调用,一直调用到目标元素上的事件监听器为止。可以在将 e.addEventListener()
的第三个参数设置为 true
时,为元素 e
注册捕获事件处理程序,并且在事件传播的第一个阶段调用。此外,事件捕获并不是一个通用的技术,在低于 IE9 版本的浏览器中无法使用。而事件冒泡则与事件捕获的表现相反,它会从目标元素向外传播事件,由内而外直到最外层。
阻止原生事件传播需要使用 e.preventDefault()
CSS Modules 的命名规范是从 BEM 扩展而来的。BEM 把样式名分为 3 个级别,具体如下所示。
- Block:对应模块名,如 Dialog。
- Element:对应模块中的节点名 Confirm Button。
- Modifier:对应节点相关的状态,如 disabled 和 highlight。
BEM 最终得到的 class
名为 dialog__confirm-button--highlight
。使用双符号 __
和 --
是为了与区块内单词间的分隔符区分开来。
从动画体验的角度来说,不同的缓动函数会带给用户不同的缓动体验。以我们常见的缓动函数 linear
、ease
和 spring
为例,缓动体验一般为 linear
< ease
< spring
。
为什么这么说呢?linear
、ease
和 spring
其实刚好代表 3 种缓动函数类型。其中,linear
是一种匀速运动, 给人的感觉是机械、呆板、没有生机,只有工厂里的机器是保持速度一成不变的!人们喜欢有生命的运动。
ease
、spring
都是变速运动,那么为什么 spring
的缓动体验要比 ease
更好呢?物理原则是优秀用户体验(UX)的核心原则之一,界面设计遵从物体在真实世界中的运动规律,会让人们感觉更加自然、舒适。
spring
是最经典、最常用的物理缓动过程。而 cubic-bezier(三次贝塞尔曲线) 因为具有很强的控制能力,人们可以非常简单、直观地配置一条 y - t
曲线作为缓动过程。因此,spring
和 cubic-bezier(如 ease
、ease-in
、ease-out
、ease-in-out
、linear
)在动画中最为常用。
在 Web 开发中,要将更新的数据实时反应到 UI 上,就不可避免地需要对 DOM 进行操作,而复杂频繁的 DOM 操作通常是产生性能瓶颈的原因之一。为此,React 引入了 Virtual DOM 机制。毫不夸张地说,Virtual DOM 是 React 的核心与精髓所在,而 reconciler 就是实现 Virtual DOM 的主要源码。
Virtual DOM 实际上是在浏览器端用 JavaScript 实现的一套 DOM API,它之于 React 就好似一个虚拟空间,包括一整套 Virtual DOM 模型、生命周期的维护和管理、性能高效的 diff 算法和将 Virtual DOM 展示为原生 DOM 的 Patch 方法等。
基于 React 进行开发时,所有的 DOM 树都是通过 Virtual DOM 构造的。React 在 Virtual DOM 上实现了 DOM diff 算法,当数据更新时,会通过 diff 寻找到需要变更的 DOM 节点,并只对变化的部分进行实际的浏览器的 DOM 更新,而不是重新渲染整个 DOM 树。
diff算法:
首先,对新集合中的节点进行循环遍历 for (name in nextChildren)
,通过唯一的 key 判断新旧集合中是否存在相同的节点 if (prevChild === nextChild)
,如果存在相同节点,则进行移动操作,但在移动前需要将当前节点在旧集合中的位置与 lastIndex
进行比较 if (child._mountIndex < lastIndex)
,否则不执行该操作。这是一种顺序优化手段,lastIndex
一直在更新,表示访问过的节点在旧集合中最右的位置(即最大的位置)。如果新集合中当前访问的节点比 lastIndex
大,说明当前访问节点在旧集合中就比上一个节点位置靠后,则该节点不会影响其他节点的位置,因此不用添加到差异队列中,即不执行移动操作。只有当访问的节点比 lastIndex
小时,才需要进行移动操作。
2、JSX
jsx介绍占坑
3、Redux
参考链接:http://www.ruanyifeng.com/blo...
https://www.cnblogs.com/passk...
1、store
Store 就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个 Store。
import { createStore } from 'redux';
const store = createStore(fn);
2、stateStore
对象包含所有数据。如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。
import { createStore } from 'redux';
const store = createStore(fn);
const state = store.getState();
3、action
Action 描述当前发生的事情。改变 State 的唯一办法,就是使用 Action。它会运送数据到 Store。
const action = {
type: 'ADD_TODO',
payload: 'Learn Redux'
};
4、Action Creator
定义一个函数来生成 Action,这个函数就叫 Action Creator。
const ADD_TODO = '添加 TODO';
function addTodo(text) {
return {
type: ADD_TODO,
text
}
}
const action = addTodo('Learn Redux');
5、store.dispatch()
import { createStore } from 'redux';
const store = createStore(fn);
store.dispatch({
type: 'ADD_TODO',
payload: 'Learn Redux'
});
6、reducer
Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。
Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。
const reducer = function (state, action) {
// ...
return new_state;
};
store.dispatch
方法会触发 Reducer 的自动执行。为此,Store 需要知道 Reducer 函数,做法就是在生成 Store 的时候,将 Reducer 传入createStore
方法。以后每当store.dispatch
发送过来一个新的 Action,就会自动调用 Reducer,得到新的 State。
import { createStore } from 'redux';
const store = createStore(reducer);
7、store.subscribe()
Store 允许使用store.subscribe
方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。
import { createStore } from 'redux'; const store = createStore(reducer); store.subscribe(listener);
4、代码编写
安装
npm install create-react-app -g
启动项目
npm start
然后把src文件夹中除了index.js的其他文件都删掉。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。