目录
一、介绍:
react:最早来源于FaceBook,后来因为其独特的设计思想和惊人的性能被广大用户喜欢,现在是最受欢迎的前端框架之一。
reflux: React的设计目的是管理视图层,所以对于大型应用来说,我们还需要数据层面的复用。所以 facebook设计了flux架构,并官方发布了dispather.js, 但是这个使用起来比较复杂,于是后来就有了更加简单的版本:reflux.
二、特征:
1、react 出现的前景:
随着ajax的出现,页面与用户的交互越来越人性化,使得大量复杂的业务逻辑从后端开发改为由前端开发实现,这使得前端代码量呈几何式增加,量变引起质变,如何组织管理这种量级的前端代码?如何更好的提升应用性能?借鉴几十年来后端开发的经验,毫不意外,答案是使用大型前端框架。
对于逻辑复杂的SPA应用,原有前端框架性能不佳,在 React 问世之前,已经有 Angular.js 等成熟的大型前端框架了,然而 Facebook 的工程师们发现,在面对复杂的业务场景(例如:频繁操作DOM)时,这些框架都无法带来良好的页面性能,于是他们打算着手自己开发一个框架解决这一问题,所开发出的框架即是 React,而对于这一问题的解决方案则是:使用虚拟 DOM。
2、虚拟DOM:
我们知道频繁的 DOM 操作会导致浏览器对 DOM 树进行大量计算,这是前端最重要的性能瓶颈。因此,只要我们能够合并多次的 DOM 操作,然后“毕其功于一役”,适时的,一次性的对 DOM 树集中进行一次操作,就可以大大提升前端性能。对于 React 而言,实现这一思路的方案即是使用 虚拟 DOM。我们所谓的 DOM 树其实就是一个树状结构嵌套的 JavaScript 对象。而在浏览器中,DOM 树的改动会造成浏览器一系列的计算,因此我们可以基于现有的 DOM 树结构,克隆出一份一模一样的 DOM 树,即“虚拟 DOM ”,将所有的改动都实现在这棵虚拟 DOM 上,然后统一合并至浏览器中的 DOM 树中以解决之前所提到的性能瓶颈。
3、组件化开发:
组件化是一种代码设计模式,它表现为你能够将一些简单的函数构建为一个更加复杂的函数加以使用。
4、函数式编程:
让开发者按照“我要做什么”,而不是“我要让计算机做什么”去思考如何实现业务需求。
5、单向数据流:
在 React 中,数据的组织形式是树状的,由上至下单向流动(对应DOM树),之所以这样设计,是因为:数据流更清晰,组件的状态就更可控;只允许数据从父元素流至子元素。
6、纯粹JavaScript语法:
在 React 中,没有任何特殊的专有的 React 语法需要理解和记忆,所有的组件,数据操作,业务逻辑都是通过使用 JavaScript 语法实现的。
三、组成:
主要模块:React,antd、Reflux、react-router
React负责页面加载、页面组装,状态管理、事件处理等
Antd负责UI组件等
Reflux负责数据流和状态缓存
React-router负责页面跳转
四、react 的基本概念:
1、状态管理:
React的状态包括可修改的state,和不可修改的props
State保存页面中所有输入输出对象的值,和数据库交互的记录集、运行状态等
Props用于父对象向子对象传递数据
2、state :
状态,它只是用来控制这个组件本身自己的状态,我们可以用state来完成对行为的控制、数据的更新、界面的渲染,由于组件不能修改传入的props,所以需要记录自身的数据变化。
setState,当我们调用这个函数的时候,React.js 会更新组件的状态 state ,并且重新调用 render 方法,然后再把 render 方法所渲染的最新的内容显示到页面上。React.js 并不会马上修改 state。而是把这个对象放到一个更新队列里面,稍后才会从队列当中把新的状态提取出来合并到 state 当中,然后再触发组件更新。是异步更新组建的。
3、prop:
react中说的单向数据流值说的就是props,根据这一特点它还有一个作用:组件之间的通信。props本身是不可变的,但是有一种情形它貌似可变,即是将父组件的state作为子组件的props,当父组件的state改变,子组件的props也跟着改变,其实它仍旧遵循了这一定律:props是不可更改的。
以下给props和state做一个总结:
-
props用于定义外部接口,state用于记录内部状态
-
props的赋值在于外部世界使用组件,state的赋值在于组件内部
-
组件不应该改变props的值,而state存在的目的就是让组件来修改的
五、JSX语法:
利用HTML语法来创建虚拟DOM:
1) 不能出现JavaScript关键字。
2)JS语句要放在{}中。
3)JSX中绑定事件,如果需要使用this,或需要传参,需要.bind(this,参数)
4) JSX中使用样式style = { {color: ‘#000’, backgroundColor: ‘#eee’} }
5) 首字母大写会识别为react组件。
六、生命周期:
页面第一次加载时
getDefaultProps getInitialState componentWillMount render componentDidMount |
1、创建阶段
该阶段主要发生在创建组件类的时候,即调用React.createClass的时候。这个阶段只会触发一个getDefaultProps方法,该方法返回一个对象,并且缓存下来。然后与父组件指定的props对象合并,最后赋值给this.props作为该组件的默认属性。对于那些没有被父辈组件指定的props属性的新建实例来说,这个方法返回的对象可用于为实例设置默认的props值。
2、实例化阶段
getInitialState
初始化组件的state的值,其返回值会赋值给组件的this.state属性。对于组件的每个实例来说,这个方法的调用次数有且只有一次。与getDefaultProps方法不同的是,每次实例创建时该方法都会被调用一次。
componentWillMount
此方法会在完成首次渲染之前被调用。这也是在render方法调用前可以修改组件state的最后一次机会。
render
生成页面需要的虚拟DOM结构,用来表示组件的输出。render方法需要满足:
(1)只能通过this.props和this.state访问数据;
(2)可以返回null、false或者任何React组件;
(3)只能出现一个顶级组件;
(4)必需纯净,意味着不能改变组件的状态或者修改DOM的输出。
返回的内容要使用JSX语法
componentDidMount
该方法发生在render方法成功调用并且真实的DOM已经被渲染之后,在该函数内部可以通过this.getDOMNode()来获取当前组件的节点。然后就可以像Web开发中的那样操作里面的DOM元素了。
页面已经存在时
componentWillReceiveProps shouldComponentUpdate componentWillUpdate render componentDidUpdate |
3、存在期
componentWillReceiveProps
在任意时刻,组件的props都可以通过父辈组件来更改。当组件接收到新的props(这里不同于state)时,会触发该函数,我们同时也获得更改props对象及更新state的机会。
shouldComponentUpdate
该方法用来拦截新的props和state,然后开发者可以根据自己设定逻辑,做出要不要更新render的决定,让它更快。
componentWillUpdate
与componentWillMount方法类似,组件上会接收到新的props或者state渲染之前,调用该方法。但是不可以在该方法中更新state和props。
render
生成页面需要的虚拟DOM结构,并返回该结构
componentDidUpdate
与componentDidMount类似,更新已经渲染好的DOM。
七、简单的使用:
1、创建 action:
'use strict';
import Reflux from 'reflux';
let ScanAppActions = Reflux.createActions([
'initScanApp',
'retrieveScanApp',
'retrieveFunContent',
'retrieveAppTxn',
'updateAppInfo'
]);
module.exports = ScanAppActions;
2、创建 store:
var Reflux = require('reflux');
var ScanAppActions = require('../action/CaseAppActions');
var CaseAppStore = Reflux.createStore({
listenables: [ScanAppActions],
filter: '',
inputData:'',
recordSet: [],
rootNodes:[],
fireEvent: function (operation, errMsg, self) {
self.trigger({
filter: self.filter,
inputData: self.inputData,
coumns:self.coumns,
recordSet: self.recordSet,
operation: operation,
errMsg: errMsg
});
MsgActions.showError('scan-app', operation, errMsg);
},
});
module.exports = CaseAppStore;
3、组件:
'use strict';
import React from 'react';
import {Tabs, Button, Icon, Collapse, Spin, Modal,Input} from 'antd';
import InterfaceTree from "./components/InterfaceTree";
const Search = Input.Search;
import EditableTable from "./components/EditableTable";
import CaseAppStore from './data/CaseAppStore';
const TabPane = Tabs.TabPane;
class CasePage extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: true,
loading: false,
pathSet: {
recordSet: [],
startPage: 1,
pageRow: 10,
totalRow: 0,
},
}
}
componentDidMount() {
this.unsubscribe = CaseAppStore.listen(this.onServiceComplete);
this.setState({loading: true});
// RoleActions.initRolePage();
}
componentWillUnmount() {
this.unsubscribe();
}
onServiceComplete = (data) => {
this.setState({
loading: false,
pathSet: data
});
}
handleQueryClick = (event) => {
this.setState({ loading: true });
let dataSet = this.state.dataSet;
}
onTableRefresh = (current, pageRow) => {
}
handleOpenCreateModel = (event) => {
}
//定义一个拿子组件返回值this的函数
checkFunRef = (ref) => {
this.child = ref
console.log("page"+this.child );
}
onSelectTxn = (txn) => {
// this.setState({ activeTxn: txn });
}
render() {
return (
<div style={{display: 'flex', height: '100%'}}>
<div style={{ flex: '0 0 400px', width: '400px', overflowX: 'hidden', borderRight: '1px solid #e2e2e2' }} >
<div style={{ padding: '8px 2px 8px 10px' }}>
<InterfaceTree onRef={this.checkFunRef} />
</div>
</div>
<div style={{ overflowX: 'hidden', width: '100%',paddingLeft:'5px',paddingTop:'10px'}}>
<div className={"buttonBtn"} style={{color:'#fefefe'}}>
</div>
<div style={{ paddingTop: '12px', paddingBottom: '16px' ,overflowX: 'auto'}}>
<EditableTable
onRef={this.checkFunRef}
txn={this.child}
/>
</div>
</div>
</div>
);
}
}
export default CasePage;
数据流转:
page 事件触发 -> action 调用方法 ->store 监听到action 被调用 ,执行对应调用的方法 ,调用后端拿到数据——>
tigger 广播数据,->page监听 store 数据变动 callback 会掉函数 调用 本组件的setstate 方法 ,更新rander 虚拟Dom,最后合并到 真实的dom树中,页面重新渲染,完成 操作。
react 和reflux :大体上,react负责展示,reflux 负责数据流转 。再具体点: react 就是组件,而 action 和 store 就属于 reflux 范畴。