这是一个基于mobx在react上的一个优化实践。
- model必须是提前创建,在总分支顶部插入。
- 方法名称变更:this.then => this.$next;
npm install moli-react --save
- 1、使用了
inject
,bound
两个装饰器的ComponentClass,ComponentClass均有state
,$next
两个属性,通过this.state
,this.$next
可以访问到。this.state
里的值都是observabled;this.$next
是this.state
发生变化,导致render之后的回调,可以这里获取到最新的真实dom结构。 - 2、改写了this.setState方法,this.setState也是一个action,同时this.setState()过之后的this.state依旧是原来的那个(保持this.state的observable)
这是一颗状态树。跟redux
的store
的概念是一样的,全局只有唯一的一颗
schema
是指store
里用户自定义的对象,即store
里每个key
的value(值)
。这里将redux
所定义的每个组件的状态扁平化了。moli-react
只允许store
设计成一级的形式,尽可能的扁平化store
.schema
是一个基础模式,当通过moli-react
的inject
方法把schema
的状态给注入到具体的某个组件的时候,这个组件就可以通过this.props.$[schema]
(我在这里定义为model模型
)获取到schema
的状态。schema
之间最好不要互相调用。
moli-react
的inject
方法把schema
的状态给注入到具体的某个组件的时候,这个组件就可以通过this.props.$[schema]
(我在这里定义为model模型
),在组件里可以通过this.props.$[schema]
获取到一个实例化的Model
moli-react
的bound
方法可以使ComponentClass拥有 this.state
和 this.$next
属性。inject
默认就给ComponentClass添加了this.state
和 this.$next
属性。
使用createStore
可以生成store,一定要在组件路由的顶层注入store,否则将会影响inject
功能的使用
createStore接收一个object作为初始化,如:
import {createStore} from 'moli-react'
createStore({
items:{
state:{
list:[]
},
computed:{
}
},
mode: {
// 初始state
state: {
editMode: false
},
changeMode(mode) {
this.editMode = mode
},
computed:{
unEdit()
return !this.editMode
}
}
}
})
createStore
所接收的对象(schemas
)的key将作为Model的name,方便inject
使用时,可以直接inject('mode')
的形式将mode
这个model直接注入到Component,schemas
值也必须是一个Object(schema
);schema
中的state
将作为初始化的initialState
;schema
中的computed
是实时计算的的值,可以作为this[key]
输出,这个值是只读的。schema
中的function都是action(mobx所定义的action)
。
@inject
将把所有在store里的schema
实例化为Model
注入到组件里。
@inject('mode')
,表示只把mode这个Model注入到ComponentClass里。
也可以使用Array作为参数,如:
@inject(['mode','items'])
,表示吧mode
,itmes
这个两个模式传入到了ComponentClass
在ComponentClass里可以通过props[$name]
获取到注入的Model,如:this.props.$mode
= mode
这个Model;
具体事例:
@inject(['items', 'mode'])
export default class List extends Component {
constructor(props) {
super(props);
}
render() {
const { list, completedList, activeList } = this.props.$items;
const { mode } = this.props.$mode;
const modeSwitcher = {
'all': () => list,
'completed': () => completedList,
'active': () => activeList
};
let _list = modeSwitcher[mode]();
return (
<section className="main">
<ul className="todo-list">
{
_list.map((item, index) => {
return <TodoItem
key={index}
item={item}
index={index}
/>
})
}
</ul>
</section>
)
}
}
bound 将使得ComponentClass的state变成可观察,并且给组件增加了this.$next
方法
import {action,bound} from 'moli-react';
@bound // 注册在ComponentClass上面可以让组件的this.state变成可以观察的,增加了this.$next 的异步方法
export default class TodoItem extends React.Component {
constructor(props) {
super(props)
// 使用bound,将使得 this.state是一个可观察的对象。
this.state = {
value: '',
editMode: false
}
}
@action // 严格模式下,改变state的方法必须要包裹一下action
handleDoubleClick(item = {}) {
this.state.value = item.value || '';
this.state.editMode = true;
// this.$next 完成 render 之后的回调
this.$next(this.focus);
}
// afterRender的回调
focus() {
this.refs.edit.focus()
this.$next(() => { this.state.value = 2333 })
}
render() {
}
}
action = mobx.action.bound 实际上就是mobx的action.bound
先安装 nscript
[sudo] npm install nscript -g
nscript publish.js