[react-control-center tutorial 1] cc.startup
react
注:本教程針對的有必定react基礎知識的用戶,如無任何react只是瞭解或者開發經驗,能夠先經過
create-react-app
快速跑起來一個應用並結合官網的知識介紹,再來閱讀此文, 對於react開發者能夠運行起來quick-start項目作更深的瞭解gitquick-start demo: github.com/fantasticso…
co
和uuid
,react15和16均可以使用cc和redux最大的不一樣之一就是,redux須要在你的頂層App組件以外包裹一個
Provider
組件,用於全局注入和管理redux
的上下文context,對於cc來講只須要在你定義好cc的啓動腳本,而後在你的代碼入口文件的第一行裏引用改腳本,就能夠完成cc的啓動工做了,因此使用cc並不會對你現有的代碼形成任何入侵,你能夠漸進式的在已有項目裏局部使用cc,嘗試cc的有趣且強大的功能github後續會放出and-design-pro的cc版本,改動的代碼不超過100行,就完美將其狀態管理框架redux遷移到ccredux
cc支持以模塊化的方式和非模塊的方式啓動起來,若是以非模塊的方式啓動,cc的store只會有兩個內建的模塊存在,即
$$global
和$$default
模塊,若是以模塊化的方式啓動,則須要用戶顯示的劃分好模塊並做爲配置參數交個cc啓動讓cc按照用戶的規劃理念啓動起來。 啓動起來以後:後端
- cc將cc的store綁定到了window.sss下。
- cc將cc的頂層api綁定到window.cc下。
- cc將cc的上下文管理對象綁定到window.ccc下和window.CC_CONTEXT下
用戶能夠在console裏經過sss能夠查看當前狀態樹的最新狀態,經過cc直接調用cc提供給開發者的頂層api與各個cc組件產生有趣的互動,這是cc讓用戶可以體會到cc的強大和有趣的入口之一。
/**-----------------[引入cc啓動腳本,讓整個項目可以使用cc的全部接口]--------*/
/** code in index.js */
import './startup-cc';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
/**-----------------[不寫入任何參數,直接運行cc啓動]-----------------------*/
/** code in startup-cc.js */
import cc from 'react-control-center';
cc.startup();
複製代碼
cc.startup()
,啓動了cc,在正式介紹cc的各類啓動方式和區別以前,咱們先來了解一下startup
函數的簽名介紹cc.startup(startupOption?:StartupOption);api
- @param
StartupOption.isModuleMode
是否以模塊化方式啓動cc,默認是false,cc強烈建議用戶設置此項爲true,方便用戶定義更多的模塊- @param
StartupOption.store
爲cc配置store- @param
StartupOption.reducer
爲cc配置reducer,reducer是一堆按模塊劃分的函數集合,能夠是普通函數、生成器函數、async函數,每一cc實例上均可以經過this.$$dispatch派發action對象調用reducer裏的函數,修改響應模塊裏的值- @param
StartupOption.computed
爲cc配置computed,這裏配置的是模塊級別的computed,在cc實例裏經過this.$$moduleComputed取到計算後的值- @param
StartupOption.init
爲cc配置init,一般是須要從後端獲取後再次賦值給store才須要配置此項- @param
StartupOption.sharedToGlobalMapping
爲cc配置sharedToGlobalMapping,用戶須要把一些模塊的值映射到$$global模塊時,須要配置此項- @param
StartupOption.moduleSingleClass
爲cc配置moduleSingleClass
,標記哪些模塊只能註冊生成一個ccClass,默認cc容許一個模塊註冊生成多個cc類
,moduleSingleClass
是一個對象,key爲moduleName
,值爲布爾值,true就表示這個模塊只容許註冊一個cc類
你們能夠先對這些這些參數有個印象,閱讀後面的講解再逐步理解透這裏面每個參數的具體做用
非模塊化啓動,cc會內置兩個模塊
$$default
、$$global
一個模塊必定包含state
,reducer
、init
、computed
是可選項,根據用戶的實際狀況考慮是否配置bash
非模塊方式一般適用於小規模的應用,狀態劃分簡單,邊界清晰,智能組件較少,開發時對狀態的修改都比較清晰,業務上這些組件的領域分類不是很明顯,例如基於react寫一個表單提交(固然這只是舉例,一般一個表單就不須要寫成一個單頁面應用了,可是若是是寫一個生成通用表單的平臺,爲了方便維護和擴展,享受現代js開發ui帶來的友好體驗,開發者一般仍是會選擇一個ui庫和狀態管理庫)app
/**-----------------[引入cc啓動腳本,讓整個項目可以使用cc的全部接口]--------*/
/** code in index.js */
import './startup-cc';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
/**-----------------[不寫入任何參數,直接運行cc啓動]-----------------------*/
/** code in startup-cc.js */
import cc from 'react-control-center';
// 缺省參數啓動cc,cc會默認生成兩個模塊$$default、$$global
cc.startup();
// 在console裏輸入sss, 能夠查看到狀態樹形如: {$$default:{}, $$global:{}}
複製代碼
$$global
模塊和$$default
模塊啓動經過上面咱們知道以非模塊化方式啓動cc時,cc會自動建立2個模塊
$$default
、$$global
,可是cc也容許用戶顯示的申明兩個模塊的值, 爲StartupOption.store
配置一個初始化的狀態樹
當用戶顯示的把store的key寫爲global或者default任意之一時,cc把store的key當作模塊名,將global或者default對應的對象賦值給cc對應global模塊或者default模塊的狀態樹,其餘多餘的key會被cc警告用戶使用模塊化方式啓動才能識別,可是cc只會警告用戶,而後忽略這key的值啓動起來框架
/**-----------------[規劃模塊參數啓動cc]----------------------------------*/
/** code in startup-cc.js */
import cc from 'react-control-center';
// 經過上面咱們知道以非模塊化方式啓動cc時,cc會自動建立2個模塊$$default、$$global
// 可是cc也容許用戶顯示的申明兩個模塊的值, StartupOption.store 爲cc初始化一個狀態樹
// 當用戶顯示的把store的key寫爲$$global或者$default任意之一時,cc把store的key當作
// 模塊名,將$$global或者$$default對應的對象賦值給cc對應$$global模塊或者$$default
// 模塊的狀態樹,其餘多餘的key會被cc警告用戶使用模塊化方式啓動才能識別,可是cc只會警告
// 用戶,而後忽略這key的值啓動起來
cc.startup({
store:{
$$global:{
themeColor:'pink',
module:'pink',
},
$$default:{
foo:'foo',
bar:'bar'
},
thisModuleWillBeenIgnored:{// 這對於cc來講是一個無效的模塊聲明
foo:'foo',
}
}
});
// 若是store直接賦值一個普通對象,不包含任何名字爲$$default、$$global的key,cc默認
// 將這個對象處理爲$$default模塊的對象
cc.startup({
store:{
themeColor:'pink',
module:'pink',
}
});
複製代碼
$$global
模塊和$$default
模塊啓動,爲$$global
模塊配置reducer
、init
、computed
/** code in startup-cc.js */
import cc from 'react-control-center';
cc.startup({
store:{
$$global:{
themeColor:'',
module:'pink',
bonus:0,
recommendedLink:'',
},
$$default:{
foo:'foo',
bar:'bar'
}
},
reducer:{
$$global:{
changeThemeColor:function* ({payload:{userId, color}}){
// 修改主題色,用戶得到積分
const bonus = yield api.changeThemeColor({userId, color});
return {bonus};
},
recoverOriginalThemeColor:async function({payload:{userId}, dispatch}){
// 恢復最初的主題色,各一個推薦連接
const recommendedLink = yield api.recoverOriginalThemeColor({userId});
dispatch({reducerModule:'whatever',type:'trackUser', payload:'wow wow'});
return {recommendedLink};
}
},
// 注意此處申明瞭whaterver當作模塊值,可是whaterver並無在store裏聲明過,cc是容許用戶這樣作的,由於cc認爲recuder能夠有本身的模塊劃分定義,實際上當用戶在cc實例裏調用dispatch時,
// 會形如this.$$dispatch({reducerModule:'whatever',type:'trackUser',payload:'cool'})這樣,
// cc會找到對應reducer模塊whatever的type爲trackUser的函數去執行數據修改邏輯,
// this.$$dispatch裏不指定reducerModule,默認會找Action對象裏指定的module當作reducerModule,
// Action對對象裏沒有指定module,會把當前cc實例所屬的module當作reducerModule
whaterver:{
trackUser: function*(){
// ... ...
}
}
},
init:{
$$global:setState=>{
api.getInitThemeColor(themeColor=>{
setState({themeColor});
})
}
},
computed:{
$$global:{
themeColor(themeColor){// 當themeColor發生變化時,計算新的值,cc實例裏的this.$$globalComputed.themeColor能夠取到
return {spanBorder:`2px solid ${themeColor}`, pBorder:`8px solid ${themeColor}`};
}
},
$default:{
foo(foo){// 反轉foo字符串, cc實例裏this.$$moduleComputed.foo能夠取到改計算值
return foo.split('').reverse().join('');
}
}
}
});
複製代碼
須要在StartOption顯示的設定
isModuleMode
爲true,其餘方式和上面的非模塊的方式同樣,惟一不一樣的是cc容許你使用其餘名字做爲模塊名了,還容許你自定義StartOption.sharedToGlobalMapping
將某些模塊裏的某些key起個別名映射到$$global
模塊裏.
cc提供sharedToGlobalMapping
是由於在cc世界裏,一個cc類只能觀察註冊的所屬模塊的狀態變化(即一個cc類直屬於一個模塊),可是全部cc類都可以觀察global模塊的轉態變化,當cc類須要觀察其餘模塊的某些key的狀態變化時,須要那個模塊先將它的這些key映射到$$global
裏,而後cc類觀察映射到$$global
裏的這些key,就達到了一個cc類
能夠觀察多個模塊變化的目的dom
/** code in startup-cc.js */
import cc from 'react-control-center';
cc.startup({
store:{
$$global:{
themeColor:'',
module:'pink',
bonus:0,
recommendedLink:'',
},
$$default:{
foo:'foo',
bar:'bar'
},
foo:{
f1:'f1',
f2:'f2',
},
bar:{
f1:'f1',
f2:'f2',
}
},
//其餘配置略 .......
// 映射時注意命名衝突
sharedToGlobalMapping:{
// 如下配置將foo模塊的f一、f2字段映射到$$global裏,由於$$global沒有名字爲f一、f2的字段,這裏就再也不起別名了
foo:{
f1:'f1',
f2:'f2',
},
// 如下配置將bar模塊的f一、f2字段映射到$$global裏分別爲bf一、bf2,由於$$global模塊裏已經存在了f1,f2,因此這裏起了別名
bar:{
f1:'bf1',
f2:'bf2',
}
}
}
複製代碼
startup
的解釋相信很多讀者必定還有疑問,由於提早提到了一些後面還會進一步詳細解釋的名詞概念,
- 好比配合講解
reducer
時提到了cc實例的$$dispatch
,- 配合講解
sharedToGlobalMapping
時,提到了觀察多個模塊狀態變化,cc除了使用sharedToGlobalMapping
達到觀察多個模塊狀態變化的目的,還提供更強大的方式,註冊爲cc類時候聲明stateToPropMapping
,能夠不用把目標觀察模塊的key映射到$$global
就可以觀察其餘模塊的狀態變化,後面會作詳解- 提到了一個
模塊
能夠註冊多個cc類
,整個cc世界裏,cc類
、react類
、和模塊
的關係會以下圖,你們能夠先作簡單瞭解,後面再回顧此圖會理解更深
quick-start demo: github.com/fantasticso…