视图与事务,好一对冤家
事务型model
model
是需求精心的规划和合理的区分的,这是咱们之前开发大型的redux
+react
单页面运用,咱们都认同的真理,同样的,在react-control-center
+react
的开发里也适用这条黄金规则,一般,咱们在接到需求,定制开发方案的时分,会抽象出许多事务相关的关键词,这些关键词渐渐经过进一步整理,将成为咱们区分功用或许模块的有效根据,这些模块最终在前端这里会沉积为model
,每一个model
界说了自己的state
、reducer
,当然如果有需求,还可认为其界说computed
、init
,经过精心的目录组织和规范的约好,视图的烘托逻辑和咱们书写的事务逻辑被有效的解耦到component
里和reducer
里,这样当咱们需求重构UI组件,能够定心的对其重构或许新增一个组件,复用相同的state
和reducer
参阅cc-antd-pro的区分
|________layouts
| |________BasicLayout.js
| |________BasicLayout.less
| |________BlankLayout.js
| |________PageHeaderLayout.js
| |________PageHeaderLayout.less
| |________UserLayout.js
| |________UserLayout.less
|________models
| |________activities.js
| |________chart.js
| |________form.js
| |________global.js
| |________index.js
| |________list.js
| |________login.js
| |________monitor.js
| |________profile.js
| |________project.js
| |________register.js
| |________rule.js
| |________user.js
视图型model
有一些状况,咱们开发的过程中,发现和视图紧密相关,不同的组件在不同的生命周期阶段,都需求运用他们或许感知到他们的改变,例如右上角用户勾选的主题色,影响左下角一个抽屉的弹出策略或效果,这些状况同样需求交个状况办理结构集中办理起来,所以咱们也会这些需求规划相应的model
,这一类和主要事务逻辑不想管,但是咱们仍然需求精心办理起来的model
,咱们称之为视图型model
.
视图代码膨胀之困惑
一般,咱们已开端精心规划好各种model
后,开端决心满满的进入开发流程,跟着功用迭代越来越块,需求改变越来频繁,咱们的model
会不断的调整或许扩展,按照class
组件和function
组件份额2:8开的准则,咱们总是想抽出更多的function
组件,class
组件担任和和model
打通,然后从model
里拿到的数据层层派发它的所以孩子function
组件里,但是function
组件一般都不是只担任展现,仍是有不少function
组件需求修改model
的state
,所以咱们在ant-design-pro
里或许其他地方,仍然会看到不少类似代码
@connect(state => ({
register: state.register,
}))
class Foo extends Component {
render(){
return (
<MyStatelessFoo {...this.props}/>
);
}
}
const MyStatelessFoo = ({dispatch}){
return <div onClick={dispatch('foo/changeSomething')}>whaterver</div>
}
如果有function
组件Foo1
、Foo2
、Foo3
,Foo1
嵌套了Foo2
,Foo2
嵌套了Foo3
,看起来要一层一层传递下去了。
一起视图组件调整的时间占比会远大于reducer
函数的书写,咱们有时分为了那个某个model
的state
,不断的传递下去或许渐渐的将某些比较重的function
组件又提升为class
组件
react hooks处理了什么呢?
这里复制一段facebook引出hooks
要处理的问题所在之处
- 难以重用和共享组件中的与状况相关的逻辑
- 逻辑复杂的组件难以开发与维护,当咱们的组件需求处理多个互不相关的 local state * 时,每个生命周期函数中可能会包含着各种互不相关的逻辑在里面。
- 类组件中的this添加学习本钱,类组件在根据现有东西的优化上存在少许问题。
- 由于事务改变,函数组件不得不改为类组件等等。
可是如果咱们的function
组件如果是需求共享或许修改model
的state
呢,有什么更优雅的办法处理吗?
CcFragment为你带来全新的无状况组件书写体验
一个典型的CcFragment
运用办法如下
import {CcFragment} from 'react-control-center';
//在你的一般的react组件或许cc组件里,都能够写如下代码
render() {
<div>
<span>another jsx content</span>
<hr/>
<CcFragment ccKey="toKnowWhichFragmentChangeStore" connect={{ 'foo/*': '', 'bar/a': 'a', 'bar/b': 'alias_b' }}>
{
({ propState, setState, dispatch, emit, effect, xeffect, lazyEffect, lazyXeffect }) => (
<div onClick={() => setState('foo', { name: 'cool, I can change foo module name' })}>
{/* 以上办法,你能够像在cc类组件相同的运用它们,没有差异 */}
{propState.foo.name}
{propState.bar.a}
{propState.bar.alias_b}
</div>
)
}
</CcFragment>
</div>
}
上面代码里,CcFragment
标记一个ccKey
,connect
- cc默认是会为一切
CcFragment
主动生成ccKey
的,但是咱们引荐你书写一个有意义的ccKey
,因为CcFragment
答应无状况组件直接运用setState, dispatch, emit, effect, xeffect, lazyEffect, lazyXeffect
办法去修改状况或许建议通知,这些函数的运用体验是和cc class
一摸相同,加上ccKey
,你能够在你的中间件函数里看到某一次的状况改变是由哪一个ccKey
触发的,这样未来你能够在还在方案开发中的cc-dev-tool
里检查具体的状况变迁前史,当然现在你需求检查状况改变的话,能够写一个简略的中间件函数来log
function myMiddleware(params, next) {
//params 里你能够看到本次状况改变提交的状况是什么,由什么办法触发,由那个ccKey的引用触发等
console.log('myMiddleware', params);
next();
}
cc.startup({
//...
middlewares: [myMiddleware]
});
- connect和
cc.register
、cc.connect
相同,表明该CcFragment
关注那些模块,哪些值的改变,上述示例的效果会是
1 只要
bar
模块的a
或许b
改变了,都会触发该CcFragment
的烘托
2 只要foo
模块的任意key
改变了,都会触发该CcFragment
的烘托
3 点击了div
,会去修改foo
模块的name
值,关注foo
模块name
值改变的一切cc
组件或许CcFragment
组件都会触发烘托
所以CcFragment
处理了用户在无状况组件里共享了model
数据的问题,你写的无状况组件很容易和cc store
打通,而无需在考虑抽取为cc class
组件,CcFragment
本质上和hooks
不存在冲突办理,也和现有cc class
不冲突,只是作为cc
世界里更重要的弥补,让你能够无损的运用现有的function
组件。
注意一点哦,CcFragment
本身是不会因为父组件的更新而被更新的哦,仅仅受操控于connect
参数观察的参数是否发生改变,所以它的烘托仍然是高效的。
那么心爱的各位看官,还不赶紧运用起来
- 在线示例点我
- cc版别ant-design-pro
- 基础入门项目
- runjs录像教程