# react-control-center **Repository Path**: nick_zhong/react-control-center ## Basic Information - **Project Name**: react-control-center - **Description**: cc是一个渐进式的、弱入侵的状态管理框架,可以和已有的redux混合使用,也可以独立使用,对现有的代码改造成本微乎其微;可以当做一种组件间通信的辅助工具使用,也可以当做整个项目的功能性组件服务转态管理。 cc精确的状态广播使得渲染的组件使得渲染效率异常高效,只渲染该渲染的片段; cc的渲染理念认为,功能型组件,一切渲染皆应由state的改变而触发,弱化props的地位,props只需要在contructor里感知存在; cc为state key划分了四种类型:temporary , stored , shared,global, 配上模块化的设计、sharedToGlobalMapping等高级功能,可以让开发探索更多的有趣的、简单的、高效的管理你的应用状态的可能! - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2018-12-27 - **Last Updated**: 2021-11-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # react-control-center [C_C] ## without redux、mobx, writing react app with cc is a funny way also, it's definitely worth doing! #### 介绍 * cc是一个渐进式的、弱入侵的状态管理框架,可以和已有的redux混合使用,也可以独立使用,对现有的代码改造成本微乎其微;可以当做一种组件间通信的辅助工具使用,也可以当做整个项目的功能性组件服务转态管理。 * cc精确的状态广播使得渲染的组件使得渲染效率异常高效,只渲染该渲染的片段; * cc的渲染理念认为,功能型组件,一切渲染皆应由state的改变而触发,弱化props的地位,props只需要在contructor里感知存在; * cc为state key划分了四种类型:temporary , stored , shared,global, 配上模块化的设计、sharedToGlobalMapping等高级功能,可以让开发探索更多的有趣的、简单的、高效的管理你的应用状态的可能!

react-control-center

其他

- 示例项目: https://github.com/fantasticsoul/rcc-simple-demo - 更多信息请参考 待添加。 - ![工作示意图](http://cdn.boldseas.com/img/cc-1.png) --- ## 核心api -- 顶层api ### startup > 启动cc后,才能在项目其他任何地方使用cc的所有功能,通常将cc的启动操作放在整个应用的入口文件的第一行 > * 非模块化模式,直接启动cc,cc默认将所有cc实例的状态存储到$$default模块,可以在console里通过ccc.store.getState()查看cc管理的所有状态,注册一个ccClass时,如果设置了sharedStateKeys标记想要共享的状态key,则该ccClass的所有实例都共享这些key对应的值,不设置sharedStateKeys则表示该ccClass的所有实例里的状态都是各自独立的,并不会相互共享。 随着应用规模越来越大,组件越来越多,组件间的状态都应该属于各自专有领域对应的模块,所以生产环境建议使用模块的方式来使用cc。 ``` import cc from 'react-control-center'; cc.startup() ``` > * 非模块化模式,配置store,reducer, init 启动cc, store和reducer都将默认归属到$$default模块 ``` import cc from 'react-control-center'; cc.startup( { store:{ bookList:[], readCount:200, cardList:[], }, reducer:{ 'setBookList':(setState, payload, [dispatchContext])=>{ //your code here const newBookList = payload; setState({bookList:newBookList}); } }, init: setState=>{ api.getBooks(books=>{ setState({books}) }); } } ) ``` > * 配置模块化的store,reducer, init启动cc, >> {Object} [startOption] >> {Boolean} [startOption.isStoreModuleMode] 设置为true,表示以模块化的方式启动cc >> {Object} [startOption.store] 配置的store, key代表名,value代表整个模块对应的初始化state >> {Object} [startOption.reducer] 配置的reducer, key代表reducerModule, 可以让reducerModule和store的名称保持一致,这样在ccInstance里调用this.$$dispatch时只需要指定type,cc自动会寻找同一个模块的type对应函数去处理action,当然你也可以自定义reducerModule为别的值,dispatch时设置reducerModule和type,表示寻找指定的reducerModule下的指定type的函数去处理action. value代表reducer function -- rfn. cc支持rfn为普通函数,生成器函数,async函数 ``` import cc from 'react-control-center'; cc.startup( { isStoreModuleMode:true, store:{ user:{ }, product:{ } }, reducer:{ user:{ serUser:({state, payload:user, dispatch, effect, xeffect})=>{ //your code here return {user} } } product:{ setProducts:({payload:products})=>{ //your code here setState({products}); } } } } ) ``` ### register 在cc startup后,任意地方可以向cc注册想要被cc控制的组件 ``` import cc from 'react-control-center'; import react from 'react'; class BookMenu extends react.Component{ constructor(props, context){ super(props, context); this.state = {books:[], color:'red', readCount:0}; } makeBooks = ()=>{ const books = this.state.books; books.push({name:'book_setState', author:Date.now()}); return books; } setBooks = (books)=>{ this.setState({books}); } addBookBySetState = ()=>{ const books = makeBooks(); //cc接管了setState函数,这里的setState是cc自己实现的setState函数,但是最终调用触发渲染的函数式react的setState,cc保留了react.setState的引用 this.setState({books});//该数据会同步到其他所有BookMenu实例 //this.setState({books},()=>{});//支持传入回调 } addBookByDispatch = ()=>{ const books = makeBooks(); this.$$dispatch({type:'setBooks',payload:books}); //如果是模块化的cc,需要传入module //this.$$dispatch({module:'book',type:'setBooks',payload:books}); //支持传入回调,最终触发的是 reactSetState(state, cb); //this.$$dispatch({module:'book',type:'setBooks',payload:books,cb=>{this.setState({color:'yellow'})}}); } addBookByInvoke = ()=>{ //cc的CC_CONTEXT管理着所有cc实例的引用,可以直接调用实例的任何方法 cc.invoke('BookMenu','bm1','setBooks', books); } render(){ return (
{ books.map(b=>
{b.name} --- {b.author}
) }
); } } //处于非模块化模式的cc组件,自动关注的是cc内建的$$global模块的数据 export default register('BookMenu')(BookMenu); //通过非模块化模式启动的cc,所有cc组件自动关注的是cc内建的$$global模块的数据, 选择共享的stateKeys,这样所有BookMenu的实例化组件,只要有任何一个组件通过setState改变了books,都会将books数据同步到其他所有同样关注此books数据的组件,从而触发他们的渲染 //export default register('BookMenu', {sharedStateKeys:['books']})(BookMenu); //通过模块化模式启动的cc,注明模块名称book,表示关注的是book模块的数据的变化。支持不同的类关注同一个模块的数据,共享同样的stateKeys,cc会精确的通知这些不同类的组件示例触发渲染 //export default register('BookMenu', {module:'book',sharedStateKeys:['books']})(BookMenu); ``` ``` import BookMenu from './BookMenu'; import react from 'react'; export default class App extends react.Component{ render(){
{/*每一个CC示例都要标记不重复的ccKey,如果不提供的话,cc会自动的生成一个,cc示例默认都拥有同步state的功能,在所有cc实例都销毁后,再次实例化的话,数据会从cc的store恢复回来*/} {/*默认都是接受同步数据行为或者同步数据到其他组件,通过标记ccOption.syncState=false, 该实例不再产生数据同步行为,它的setState仅仅影响自己,它实例化时,cc不会的把store的数据注入到它的state*/}
} } ``` ### invoke starup后,cc的CC_CONTEXT管理着所有cc实例的引用,可以直接调用实例的任何方法 --- ## 核心api -- cc实例定义的函数 ### cc实例的自定义生命周期函数 ``` $$beforeSetState, $$beforeBroadcastState,$$afterSetState 各自的触发时机处于以下位置 $$beforeSetState $$beforeBroadcastState(如果存在要广播的状态,此方法被调用) componentWillReceiveProps shouldComponentUpdate componentWillUpdate render componentDidUpdate $$afterSetState ``` ### cc实例的自定义$$computed函数 ``` @cc.register('Foo'); class Foo extends React.Component{ constructor(props, context){ super(props, context); this.state = { foo: 'foo', bar: 'bar', }; } $$computed = ()=>{ return { foo: foo=> `wrapped foo:${foo}`, bar: bar=> `reversed bar:${bar.split('').reverse().join('')}` } } render(){ const {foo, bar} = this.state; const {foo:cFoo, bar:cBar} = this.$$refComputed; return (

foo {foo}

bar {bar}

computed foo {cFoo}

computed bar {cBar}

); } } ``` --- ## 核心api -- cc实例运行时可以调用的函数 ### cc实例的自定义$$computed函数 --- ### 结语 * 此项目启发于redux的高阶函数,在脑海里构思了一周左右,觉得通过控制引用接管setState函数,可以精确的控制想要渲染的组件,数据都从state降低编程的复杂度 * 所有cc组件都具有相互感知到共享的key的数据变化,且组件销毁后数据能够存储的store里,使得再次实例化组件时数据能够自动恢复,让state能够变得更智能 * 有了具体的思路,整个核心源码的实现一共花了2天左右,个人的目的是让react-control-center能够在已有项目中能够局部的渐进式的使用,所以设计的非常弹性,核心api非常少,不需要你为了react-control-center而让现有项目改动特别大,使用期待大家能够给我更多的star,提出更多的issues,让react-control-center 成为一种新的状态管理工具的可选项 * 也欢迎fork和提PR,让我们为react-control-center的成长一起贡献力量,如有兴趣讨论更多有意思的功能或者给予我更多的帮助,可以直接加我QQ 624313307。 * 更多代码演示,参见我的示例项目 https://github.com/fantasticsoul/rcc-simple-demo * 第一次写README, 比较简陋,而且时间比较紧张,个人还有公司的是要开发任务要处理,所以文档目前也没有建立起来,index.d.ts也还没有添加,后期等得到更多的反馈后会逐步完善起来,期待大家通过我的示例项目体会到 react-control-center的简单与美妙,