这是我在学习react框架时的个人理解,包含个人总结和案例中代码的分析,对于react中部分与内存分配相关的原理还是不是很懂:
1.个人总结:
flux架构的理解:
flux架构中数据是单向流动的;
view[components]经过出发产生action,action通过转发器dispatchet转发至store中,在store中action被注册在action中的回调函数接收和解析,通过计算store会更新store中的数据【存放组件状态的对象】,同时发送事件信号,发送的事件信号将被添加了事件监听对象的组件监听,
当组件监听事件成功后会调用组件的this.setState()函数更新组件的状态,从而驱动组件的重新渲染过程.
flux中各种model推荐的构建的顺序:
1.Dispatch在整个应用中是全局唯一的,可以通过 new Dispatcher()创建,用于转发action;
2.创建每个组件【每类】组件对应的action,在action中接收来在组件的数据并创建action对象,通过dispatcher转发到store中,之后会调用在store中注册的回调函数,解析action更新storez中的相关数据;
3.创建组件的store,在store中存储组件的初始状态,在store中完成的工作是生成新的数据并发送更新信号;
4.创建对应的组件,在组件类中首先应该获取初始值,并添加监听函数,动作响应函数。
以上flux构建项目的步骤只是本人总结归纳的,具体的步骤以实际开发为准;
A.flux中应该注意的问题:action为一个纯函数,多次引用在每个引用model的存储空间中初始化了多分实例,但是其产出只依赖于输入,所以无论整个应用中生成的实例是唯一的还是多个对整个应用功能的实现是不影响的;
B.Dispatcher对象在多次的引用过过程中不会生成多个实例,其底层只用的是单例模式实现的,因此在flxu应用中,我们使用的dispatcher对象是全局唯一并且是所有的模块共享的;只有这样我们才能保证在Action中调用了Dispatcher.dispatch(action);之后会去调用在store中注册的回调函数计算出新的数据[一般认为这个回调函数的调用时自动完成的]。
C:每个组件对应的store在全局范围内是唯一的,这样可以办证在不同的地方进行引用时可以获得同步的数据,这是通过浅复制的原理实现的;
2.案例代码分心
action:
//action描述了组件发出的请求,包含了请求的类型和请求传递的数据;
//action是一个纯函数,其产出只依赖与输入;
//在实际的操作中,counterCasption相当于组件的ID,当组件产生动作的同时如果携带了数据,那么还可以添加对应的数据项;
import * as ActionTypes from './ActionTypes.js';
import AppDispatcher from '../dispatchers/Appdispatcher.js';
//定义action构造器;
export const increment = (counterCaption)=>{
AppDispatcher.dispatch(
{
type:ActionTypes.INCREMENT,
counterCaption:counterCaption
}
);
};
export const decrement = (counterCaption)=>{
AppDispatcher.dispatch(
{
type:ActionTypes.DECREMENT,
counterCaption:counterCaption
}
);
}
store
//CounterStore相当于一类组件的数据中心,它是单例的共享的;
//Store中包含了组件是无状态model,其中包含了组件的初始状态值,以普通对象的形式存在;
//一般在store中应该提供一个get方法,用于组件获取初始状态的值;
//store中应该为Dispatcher注册状态计算函数,用于更新计算出新的数据,当组件同步这些数据后,组件的状态会更新,渲染被驱动进行;
import AppDispatcher from '../dispatchers/Appdispatcher.js';
import * as ActionTypes from '../actions/ActionTypes';
import {EventEmitter} from 'events';
//定义监听事件;
const CHANGE_EVENT = 'changed';
//定义组件的初始值,当组件加载的时候会在声明周期函数中同步这些值到组件的状态或者属性上去;
const counterValues = {
'First': 0,
'Second': 10,
'Third': 30
};
//定义组件的store对象;
const CounterStore = Object.assign({},EventEmitter.prototype,{
//定义getter函数,方便数据的同步;
getCounterValues:function(){
return counterValues;
},
//定义事件发射函数,store中的数据发生改变的时候通知对应的组件更新数据[是否会造成所有监听到该事件的组件都去调用getter函数同步数据呢?
//会不会造成应用运行效率的降低呢];
emitChange:function(){
this.emit(CHANGE_EVENT);
},
//定义事件监听器添加函数,当组件挂载成功的时候添加监听函数;
//callbacek函数由调用者传入,用于指明监听到事件后的行为,
//通常callback函数的作用是更新组件的内部状态;
addChangeListener:function(callback){
this.on(CHANGE_EVENT,callback);
},
//监听函数移除函数;
removeChangeListener:function(callback){
this.removeListener(CHANGE_EVENT,callback);
}
});
//为store注册回调函数;
CounterStore.dispatchToken = AppDispatcher.register(
(action)=>{
if(action.type===ActionTypes.INCREMENT){
counterValues[action.counterCaption]++;
CounterStore.emitChange();
}else if(action.type===ActionTypes.DECREMENT){
counterValues[action.counterCaption]--;
CounterStore.emitChange();
}
}
);
//定义导出接口;
export default CounterStore;
dispatcher
import {Dispatcher} from 'flux';
//创建flux中的dispatcher,由flux框架控制为单例模式的;
export default new Dispatcher();
components
//定义组件;
import React, {Component, PropTypes} from 'react';
import * as Actions from '../actions/Actions';
import CounterStore from '../stores/CounterStore';
const buttonStyle = {
margin: '10px'
};
//定义组件的主体部分;
class Counter extends Component {
constructor(props) {
super(props);
//绑定this到成员函数;
this.onChange = this.onChange.bind(this);
this.onClickIncrementButton = this.onClickIncrementButton.bind(this);
this.onClickDecrementButton = this.onClickDecrementButton.bind(this);
//获取组件的初始状态;
this.state = {
count: CounterStore.getCounterValues()[props.caption]
}
}
//使用shouldComponentUpdate函数增加组件的渲染速度;
//因为当事件发射器发射事件后,所有监听该事件的组件中的主句或者状态将被更新,this.setState函数将被调用,采用shouldComponentUpdate
//函数进行判断可以提高组件的渲染效率;
shouldComponentUpdate(nextProps, nextState) {
return (nextProps.caption !== this.props.caption) || (nextState.count !== this.state.count);
}
//组件成功挂载到dom上之后添加事件的监听;
componentDidMount() {
CounterStore.addChangeListener(this.onChange);
}
//组件被移除后对应的监听也应该被移除;
componentWillUnmount(callback) {
CounterStore.removeChangeListener(this.onChange);
}
//更新组件的状态;
onChange() {
//同步store中的数据到组件中;
const newCount = CounterStore.getCounterValues()[this.props.caption];
this.setState({count: newCount});
}
onClickIncrementButton() {
Actions.increment(this.props.caption);
}
onClickDecrementButton() {
Actions.decrement(this.props.caption);
}
render() {
const {caption} = this.props;
return (<div>
<span>JunJun的计算器</span>
<button style={buttonStyle} onClick={this.onClickIncrementButton}>+</button>
<button style={buttonStyle} onClick={this.onClickDecrementButton}>-</button>
<span>{caption}count:{this.state.count}</span>
</div>);
}
}
//约束组件的属性类型;
Counter.propTypes = {
caption: PropTypes.string.isRequired
};
//声明组件的引用接口;
export default Counter;