摘要:監(jiān)聽(tīng)發(fā)射的事件。指定了,而不指定的話,去查里下的映射函數(shù)去修改模塊的。
C_C welcom to cc world
quick-start demo: https://github.com/fantastics... github地址 歡迎大家star,給我更大的動(dòng)力。簡(jiǎn)介
硝煙四起
眾所周知,react本身只是非常優(yōu)雅的解決了視圖層渲染工作,但是隨著應(yīng)用越來(lái)越大,龐大的react組件群體之間狀態(tài)相互其實(shí)并不是孤立的,需要一個(gè)方案管理把這些狀態(tài)集中管理起來(lái),從而將model和view的邊界劃分得更加清楚,針對(duì)于此,facebook官方對(duì)于react狀態(tài)管理給了一個(gè)flux架構(gòu)并有一套自己的實(shí)現(xiàn),但是社區(qū)里并不滿足于此,基于對(duì)flux的理解各個(gè)第三方做著給出了的自己的解決方案,狀態(tài)管理框架的戰(zhàn)爭(zhēng)從此拉開序幕,隨著redux橫空出世,大家默默接受了redux的 dispatch action、hit reducer、comibine new state、render new view的理念,在redux世界里,組件需要關(guān)心的狀態(tài)變化都由props注入進(jìn)來(lái),connect作為中間的橋梁將react組件與redux關(guān)聯(lián)起來(lái),通過(guò)mapStateToProps將redux里定義好的state映射到組件的props上,以此達(dá)到讓react組件訂閱它需要關(guān)心的state變化的目的。
一統(tǒng)天下
隨著redux生態(tài)逐漸完善,大家默認(rèn)的把redux當(dāng)做了react狀態(tài)管理的首選解決方案,所以redux已經(jīng)在react狀態(tài)管理框架里一統(tǒng)天下,通過(guò)github star發(fā)現(xiàn),另一個(gè)流行的狀態(tài)管理框架mobx頁(yè)已經(jīng)鎖定第二的位置,用另一種思路來(lái)給大家展示原來(lái)狀態(tài)可以這么管理,狀態(tài)管理的格局似乎基本已經(jīng)洗牌完成,可是作為redux重度使用者的我并不滿足與此,覺(jué)得在redux世界里,通過(guò)props層層穿透數(shù)據(jù),通過(guò)provider包裹整個(gè)react app應(yīng)用,只是解決了狀態(tài)的流動(dòng)問(wèn)題,而組件的通信任然非常間接與尷尬,依靠redux來(lái)完成不是不可以,只是對(duì)比vue,任然覺(jué)得少了些什么......
why cc
react-control-center并不是簡(jiǎn)單的立足于狀態(tài)管理,而是想為你提供更多的有趣玩法,因?yàn)楝F(xiàn)有的狀態(tài)管理解決方案已經(jīng)非常成熟(但是在某些場(chǎng)景未必真的好用),所以cc從一開始設(shè)計(jì)就讓其api對(duì)現(xiàn)有的組件入侵非常之小,你可以在redux項(xiàng)目里局部使用cc來(lái)把玩cc的狀態(tài)管理思路,可以從一個(gè)組件開始,慢慢在開始漸進(jìn)式的修改到其他地方,僅僅使用一個(gè)register函數(shù),將你的react類注冊(cè)為cc類,那么從cc類生成的cc實(shí)例,將給你帶來(lái)以下新的特性、新的概念、新的思路。
1 所有cc實(shí)例都擁有 emit 和 on 的能力,無(wú)論組件間嵌套關(guān)系多復(fù)雜,實(shí)現(xiàn)組件間通信將會(huì)是如此輕松。
實(shí)際上實(shí)例還擁有更精準(zhǔn)的emitIdentity, emitWith, onIdentity方法,讓用戶基于更精準(zhǔn)的力度去發(fā)射或者接收。
emitIdentity(eventName:string, identity:string, ...args), 第一位參數(shù)是事件名,第二位參數(shù)是認(rèn)證串,剩余參數(shù)是on的handler函數(shù)的實(shí)際接收參數(shù),當(dāng)很多相同組件(如以CcClass:BookItem生成了多個(gè)CcInstance)訂閱了同一個(gè)事件,但是你只希望通知其中一個(gè)觸發(fā)handler調(diào)用時(shí),emitIdentity就能派上用場(chǎng)了。
onIdentity(eventName:string, identity:string, hancler:function),監(jiān)聽(tīng)emitIdentity發(fā)射的事件。
emitWith(eventName:string, option?:{module?:string, ccClassKey?:string, identity?:string})從一個(gè)更精準(zhǔn)的角度來(lái)發(fā)射事件,尋找指定模塊下,指定cc類名的,指定identity的監(jiān)控函數(shù)去觸發(fā)執(zhí)行,具體過(guò)程這里先略過(guò),先看下面關(guān)于模塊和cc類的介紹,在回過(guò)頭來(lái)理解這里更容易。
off(eventName:string, option?:{module?:string, ccClassKey?:string, identity?:string}),取消監(jiān)聽(tīng)。
這些函數(shù)在cc的頂層api里都有暴露,當(dāng)你的cc app運(yùn)行起來(lái)之后,你可以打開console,輸入cc并回車,你會(huì)發(fā)現(xiàn)這些函數(shù)已經(jīng)全部綁定在window.cc對(duì)象下了,你可以直接調(diào)用他們來(lái)完成快速驗(yàn)證哦,而非通過(guò)ccInstance去觸發(fā)^_^
import cc from "react-control-center"; import React,{Component, Fragment} from "react"; @cc.register("Foo") class Foo extends Component{ componentDidMount(){ this.$$on("fooSignal",(signal, from)=>{ this.setState({signal, from}); }); //cc是不允許一個(gè)cc實(shí)例里對(duì)同一個(gè)事件名監(jiān)聽(tīng)多次的,這里fooSignal監(jiān)聽(tīng)了兩次,cc會(huì)默認(rèn)使用最新的監(jiān)聽(tīng)函數(shù),所以上面?zhèn)€監(jiān)聽(tīng)變成了無(wú)效的監(jiān)聽(tīng) this.$$on("fooSignal",(signal, from)=>{ this.setState({signal, from:`--${from}--`}); }); this.$$on("fooSignalWithIdentity", "xxx_id_wow",()=>{ this.setState({signal, from}); }) } } @cc.register("Bar") class Bar extends Component{ render(){} }
2 所有cc實(shí)例都可以針對(duì)自己的state的任意key定義 computed 函數(shù),cc會(huì)在key的值發(fā)生變化自動(dòng)計(jì)算新的computed值并緩存起來(lái),在實(shí)例里定義的computed會(huì)收集到實(shí)例的refComputed對(duì)象里。
import cc from "react-control-center"; import React,{Component, Fragment} from "react"; @cc.register("Foo") class Foo extends Component{ constructor(props, context){ super(props, context); this.state = {woo:"woo cc!"}; } $$computed(){ return { wow(wow){ return `computed wow ${wow}`; } } } componentDidMount(){ this.$$on("fooSignal",(signal, from)=>{ this.setState({signal, from}); }); } changeWow = (e)=>{ this.setState({wow: e.currentTarget.value}); } render(){ return ({this.state.wow} {this.$$refComputed.wow}); } }
3 注冊(cè)為cc類的時(shí)候,為該cc類設(shè)定了一個(gè)該cc類所屬的 模塊 ,并通過(guò)sharedStateKeys聲明關(guān)心該模塊里哪些key(可以是任意的key,也可以是這個(gè)模塊的所有key)的變化,則由改cc類產(chǎn)生的cc實(shí)例共同監(jiān)聽(tīng)著這些key對(duì)應(yīng)值的變化,任何一個(gè)cc實(shí)例改變了這些sharedStateKeys里的值,其他cc實(shí)例都能感知到它的變化并自動(dòng)被cc觸發(fā)渲染。
import cc from "react-control-center"; import React,{Component, Fragment} from "react"; class Foo extends Component{ render(){ returnany jsx fragment here} } //將Foo注冊(cè)為一個(gè)共享FooOfM1模塊所有key變化的cc類FooOfM1 const FooOfM1 = cc.register("FooOfM1", {module:"M1", sharedStateKeys:"all"})(Foo); //將Foo注冊(cè)為一個(gè)共享FooOfM2模塊key1和key2變化的cc類FooOfM2 const FooOfM2 = cc.register("FooOfM2", {module:"M2",sharedStateKeys:["key1","key2"]})(Foo); //將Foo注冊(cè)為一個(gè)共享FooOfM2模塊key1和key2變化,且共享global模塊g1變化的cc類FooOfM2G const FooOfM2G = cc.register("FooOfM2", {module:"M2",sharedStateKeys:["key1","key2","key3"],globalStateKeys:["g1"]})(Foo); //不設(shè)定任何參數(shù),只寫cc類名,cc會(huì)把Foo注冊(cè)為一個(gè)屬于default模塊的cc類 const JustWantToOwnCcAbility = cc.register("JustWantToOwnCcAbility")(Foo); //cc同時(shí)也為register提供簡(jiǎn)寫函數(shù) //const FooOfM2G = cc.r("FooOfM2",{m:"M2",s:["key1","key2","key3"],g:["g1"]})(Foo})
4 注意在3里我們提到一個(gè)概念 模塊,對(duì)于cc來(lái)說(shuō)一個(gè)完整的模塊包括以下屬性:state、reducer、init、computed,這些參數(shù)都是調(diào)用cc.startup時(shí)注入,注意,cc雖然不需要用戶像redux那樣要給頂層App組件包裹一層但是要求用戶在app入口文件的第一句話那里觸發(fā)cc.startup 讓整個(gè)cc運(yùn)行起來(lái),store、reducer、init、computed就是cc.startup需要的參數(shù)
store是一個(gè)object對(duì)象,store里的各個(gè)key就表示模塊名,對(duì)應(yīng)的值就是各個(gè)模塊對(duì)應(yīng)的state,一個(gè)cc實(shí)例除了setState方法能夠觸發(fā)修改state,還可以通過(guò)dispatch方法派發(fā)action對(duì)象去修改state,此時(shí)具體的數(shù)據(jù)合成邏輯就體現(xiàn)在下面要說(shuō)的reducer里了
recuder是一個(gè)object對(duì)象,recuder里的各個(gè)key表示reducer的模塊名,通常用戶可以定義和state的模塊名保持一致,但是可以定義另外的模塊名,所以這里的模塊指的是reducerModuel,不強(qiáng)求用戶定義時(shí)和stateModule保持一致,stateModule對(duì)應(yīng)的值一個(gè)普通的json對(duì)象,key為函數(shù)名,值為處理函數(shù),即處理舊state并合成新state的方法,cc支持函數(shù)為普通函數(shù)、生成器函數(shù)、async函數(shù)。
上面提到了dispatch函數(shù)需要傳遞一個(gè)action對(duì)象,一個(gè)標(biāo)準(zhǔn)的action必須包含type、payload 2個(gè)屬性,表示cc要去查recuder里某個(gè)模塊下type映射函數(shù)去修改某個(gè)模塊的state,具體是什么模塊的type映射函數(shù)和什么模塊對(duì)應(yīng)的state,參見(jiàn)action剩余的兩個(gè)可缺省的屬性module和reducerModule的設(shè)定規(guī)則,注意,這里再一次提到了reducerModule,以下規(guī)則就體現(xiàn)了為什么cc允許reducer模塊名可以自由定義:
不指定module和reducerModule的話,cc去查reducer里當(dāng)前cc實(shí)例所屬模塊下的type映射函數(shù)去修改當(dāng)前cc實(shí)例所屬模塊的state。
指定了module,而不指定reducerModule的話,cc去查reducer里module下的type映射函數(shù)去修改module模塊的state。
不指定module,指定reducerModule的話,cc去查reducer里reducerModule下type映射函數(shù)去修改當(dāng)前觸發(fā)dispatch函數(shù)的cc實(shí)例所屬的module模塊的state。
指定了module,同時(shí)也指定了reducerModule的話,cc去查reducer里reducerModule下type映射函數(shù)去修改module模塊的state。
之所以這樣設(shè)計(jì)是因?yàn)榭紤]到讓用戶可以自由選擇reducer的模塊描述方式,因?yàn)閷?duì)于cc來(lái)說(shuō),dispatch派發(fā)的action只是為了準(zhǔn)確找到reducer里的處理函數(shù),而reducer的模塊定義并不需要強(qiáng)制和state保持一致給了用戶更多的選擇去劃分reducer的領(lǐng)域init是一個(gè)object對(duì)象,key是模塊名,嚴(yán)格對(duì)應(yīng)stateModule,值是一個(gè)函數(shù),如果用戶為某個(gè)模塊定義了init函數(shù)表示用戶希望有機(jī)會(huì)再次初始化某個(gè)模塊的state,通常是異步請(qǐng)求后端來(lái)的數(shù)據(jù)重新賦值給模塊對(duì)應(yīng)的state
computed是一個(gè)object對(duì)象,key是模塊名,嚴(yán)格對(duì)應(yīng)stateModule,值是一個(gè)moduleComputedObject,moduleComputedObject的key指的就是某個(gè)module的某個(gè)key,value就是為這個(gè)key定義的計(jì)算函數(shù),函數(shù)的第一為參數(shù)就是key的原始值,cc實(shí)例里通過(guò)moduleComputed對(duì)象取到計(jì)算后的新值,特別地,為global模塊定義的moduleComputedObject對(duì)象,在cc實(shí)例里通過(guò)globalComputed對(duì)象取到計(jì)算后的新值
//code in index.js import api from "@foo/bar/api"; cc.startup({ isModuleMode:true,//表示cc以模塊化方式啟動(dòng),默認(rèn)是false,cc鼓勵(lì)用戶使用模塊化管理狀態(tài),更容易劃分領(lǐng)域的邊界 store:{ $$global{//$$global是cc的內(nèi)置模塊,用戶如果沒(méi)有顯式的定義,cc會(huì)自動(dòng)注入一個(gè),只不過(guò)是一個(gè)不包含任何key的對(duì)象 themeColor:"pink", }, m1:{ name:"zzk", age:30, books:[], error:"", }, m2:{ wow:"wow", signal:"haha", } }, reducer:{ m1:{ //state表示調(diào)用dispatch的cc實(shí)例對(duì)應(yīng)的state,moduleState只描述的是cc實(shí)例所屬的模塊的state,更多的解釋看下面的4 5 6 7 8這些點(diǎn)。 //特別的注意,如果該方法是因?yàn)槟硞€(gè)reducer的函數(shù)里調(diào)用的dispatch函數(shù)而被觸發(fā)調(diào)用的,此時(shí)的state始終指的是最初的那個(gè)在cc實(shí)例里觸發(fā)dispatch時(shí)那個(gè)cc實(shí)例的state,而moduleState始終指向的是指定的module的的state!!! changeName:function({payload,state,moduleState,dispatch}){ const newName = payload; dispatch({module:"m2",type:"changeSignal",payload:"wow!dispatch in reducer function block"}); return {name:newName}; }, //支持生成器函數(shù) changeAge:function*({payload,state,moduleState,dispatch}){ const newAge = payload; const result = yield api.verifyAge(newAge); if(result.error)return({error:result.error}); else return {name:newName}; }, //支持async changeAge:async function({payload:{pageIndex,pageSize}}){ const books = yield api.getBooks(pageIndex, pageSize); return {books}; } }, m2:{ changeSignal:function({payload:signal,dispatch}){ //注意m1/changeName里指定了修改m2模塊的數(shù)據(jù),其實(shí)這里可以一次性return {signal, wow:"just show reducerModule"}來(lái)修改數(shù)據(jù), //但是故意的調(diào)用dispatch找whatever/generateWow來(lái)觸發(fā)修改m2的wow值,是為了演示顯示的指定reducerModule的作用 dispatch({module:"m2",reducerModule:"whatever",type:"generateWow",payload:"just show reducerModule"}) return {signal}; } }, whatever:{//一個(gè)刻意和stateModule沒(méi)有保持一致的reducerModule generateWow:function({payload:wow}){ return {wow}; } }, $$global:{//為global模塊指定reducer函數(shù) changeThemeColor:function({payload:themeColor}){ return {themeColor} } } }, init:{ $$global:setState=>{//為global模塊指定state的初始化函數(shù) api.getThemeColor().then(themeColor=>{ setState({themeColor}) }).catch(err=>console.log(err)) } }, computed:{ m1:{ name(name){//reverse name return name.split("").reverse().join(""); } } } })
4 注意第3點(diǎn)里,注冊(cè)一個(gè)react類到某個(gè)模塊里成為cc類時(shí),sharedStateKeys可以是這個(gè)模塊里的任意key,因?yàn)閏c允許注冊(cè)不同的react類到同一個(gè)模塊,例如模塊M里擁有5個(gè)key為f1、f2、f3、f4、f5, ccClass1通過(guò)sharedStateKeys觀察模塊M的f1、f2, ccClass2通過(guò)sharedStateKeys觀察模塊M的f2、f3、f4,當(dāng)ccClass1的某個(gè)實(shí)例改變了f2的值,那么ccClass1的其他實(shí)例和ccClass2的所有實(shí)例都能感知到f2的變化并被cc觸發(fā)渲染。
5 cc有一個(gè)內(nèi)建的global模塊,所有的ccClass都天生的擁有觀察global模塊key值變化的能力,注冊(cè)成為cc類時(shí)通過(guò)globalStateKeys觀察模塊global里的任意key。
6 所有cc實(shí)例上可以通過(guò)prop ccOption設(shè)定storedStateKeys,表示該實(shí)例上的這些key是需要被cc存儲(chǔ)的,這樣在該cc實(shí)例銷毀然后再次掛載回來(lái)的時(shí)候,cc可以把這些key的值恢復(fù)回來(lái)。
7 一個(gè)cc實(shí)例的state的key除了上面所提到的global、 shared、stored這三種類型,剩下的一種key就是默認(rèn)的temporary類型了,這種key對(duì)應(yīng)的值隨著組件銷毀就丟失了,再次掛載cc實(shí)例時(shí)會(huì)讀取state里的默認(rèn)值。
8 結(jié)合4 5 6 7來(lái)看,cc實(shí)例里的state是由cc類上申明的sharedStateKeys、globalStateKeys,和cc實(shí)例里ccOption申明的storedStateKeys對(duì)應(yīng)的值,再加上剩下的默認(rèn)的temporaryStateKeys對(duì)應(yīng)的值合并得出來(lái)。
9 和react實(shí)例一樣,觸發(fā)cc實(shí)例render方法,依然是經(jīng)典的setState方法,以及上面提到的dispatch定位reducer方法去修改,除了這兩種cc還有更多自由的選擇,如invoke,effect,xeffect允許用戶直接調(diào)用自己定義的函數(shù)去修改state,同reducer函數(shù)一樣,可以是普通函數(shù)、generator函數(shù)、async函數(shù)。
這樣的方式讓用戶有了更多的選擇去觸發(fā)修改state,cc并不強(qiáng)制用戶使用哪一種方式,讓用戶自己摸索和組合更多的最佳實(shí)踐invoke一定是修改當(dāng)前cc實(shí)例的state,只需要傳入第一位參數(shù)為具體的用戶自定義執(zhí)行函數(shù),剩余的其他參數(shù)都是執(zhí)行函數(shù)需要的參數(shù)。
effect允許用戶修改其他模塊的state,第一位參數(shù)是moduleName,第二位參數(shù)為具體的用戶自定義執(zhí)行函數(shù),剩余的其他參數(shù)都是執(zhí)行函數(shù)需要的參數(shù)。
xeffect和effect一樣,允許用戶修改其他模塊的state,第一位參數(shù)是moduleName,第二位參數(shù)為具體的用戶自定義執(zhí)行函數(shù),剩余的其他參數(shù)都是執(zhí)行函數(shù)需要的參數(shù),和effect不一樣的地方是xeffect調(diào)用的執(zhí)行函數(shù)的參數(shù)列表,第一位是cc注入的ExecuteContext對(duì)象,里面包含了module, state, moduleState, xeffect,剩下的參數(shù)才對(duì)應(yīng)的是是用戶調(diào)用xeffect是除第一第二位參數(shù)以外的其他參數(shù)
import React,{Component, Fragment} from "react"; import cc from "react-control-center"; function* loginFn(changedBy, p1, p2 ,p3){ return {changedBy, p1:p1+"--tail", p2:"head--"+p2 ,p3} } function* forInvoke(changedBy, p1, p2 ,p3){ const result = yield loginFn(changedBy, p1, p2 ,p3); return result; } function* forEffect(changedBy, p1, p2 ,p3){ const result = yield loginFn(changedBy, p1, p2 ,p3); return result; } function* forXeffect({module, state, moduleState, xeffect}, changedBy, p1, p2 ,p3){ const result = yield loginFn(changedBy, p1, p2 ,p3); return result; } @cc.register("Foo") class Foo extends Component{ constructor(props, context){ super(props, context); this.state = {changedBy:"none", p1:"", p2:"" ,p3:""}; } render(){ const {changedBy, p1, p2, p3} = this.state; //注,該cc類模塊沒(méi)有顯式的聲明模塊,會(huì)被cc當(dāng)做$$default模塊的cc類 return (); } } changedBy {changedBy}p1 {p1} p2 {p2} p3 {p3}
10 cc定位的容器型組件的狀態(tài)管理,通常情況一些組件和model非常的有業(yè)務(wù)關(guān)系或者從屬關(guān)系,我們會(huì)把這些react類注冊(cè)為某個(gè)moudle的cc類,觀察這個(gè)模塊中的狀態(tài)變化,但是有些組件例如一個(gè)Workpace類的確需要觀察很多模塊的狀態(tài)變化,不算是某個(gè)模塊對(duì)應(yīng)的視圖組件,此時(shí)除了用上面說(shuō)的sharedToGlobalMapping功能,將需要觀察各個(gè)模塊的部分狀態(tài)映射到global里,然后注冊(cè)Workpace時(shí)為其設(shè)定globalStateKeys,就能達(dá)到觀察多個(gè)模塊的狀態(tài)變化的目的之外,cc還提供另一種思路,注冊(cè)Workpace時(shí)設(shè)定stateToPropMapping,就可以觀察恩義模塊的任意key的值變化,和sharedToGlobalMapping不同之處在于,stateToPropMapping要從this.$$propState里取值,sharedToGlobalMapping是從this.state取值,當(dāng)然stateToPropMapping不需要模塊主動(dòng)的將某些key映射到global里,就能達(dá)到跨模塊觀察狀態(tài)變化的目錄,cc鼓勵(lì)用戶精確對(duì)狀態(tài)歸類,并探索最佳組合和最佳實(shí)踐
// these code written in https://github.com/fantasticsoul/rcc-simple-demo/tree/master/src/cc-use-case/WatchMultiModule // you can update the rcc-simple-demo lastest version, and run it, then switch tab watch-multi-module, you will see what happen import React from "react"; import cc from "react-control-center"; class WatchMultiModule extends React.Component { render() { console.log("%c@@@ WatchMultiModule", "color:green; border:1px solid green;"); console.log(`type cc.setState("todo",{todoList:[{id:Date.now()+"_1",type:"todo",content:"nono"},{id:Date.now()+"_2",type:"todo",content:"nono"}]}) in console`); const { gbc, alias_content, counter_result, todoList } = this.$$propState; return (); } } const stateToPropMapping = { "$$global/borderColor": "gbc", "$$global/content": "alias_content", "counter/result": "counter_result", "todo/todoList": "todoList", }; //two way to declare watching multi module cc class export default cc.connect("WatchMultiModule", stateToPropMapping)(WatchMultiModule); //export default cc.register("WatchMultiModule", {stateToPropMapping})(WatchMultiModule);open your consoletype and then enter to see what happen cc.setState("counter",{result : 888} )type and then enter to see what happen cc.setGlobalState( {content:"wowowo"} );{gbc}{alias_content}{counter_result}{todoList.length}
github地址:https://github.com/fantastics...
gitee地址:https://gitee.com/nick_zhong/...
quick-start demo: https://github.com/fantastics...
期待大家試用并給出修改意見(jiàn),真心希望能夠親愛(ài)你的能夠感受的cc的魅力和強(qiáng)大,因?yàn)樽鳛閞edux使用者的我(3年了快),不管是用了原生的redux還是dva封裝后的redux,個(gè)人都覺(jué)得沒(méi)有cc使用那么的爽快......先從示例項(xiàng)目開始體驗(yàn)吧^_^,期待著你和我有一樣的感受
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/101035.html
手挽手帶你學(xué)React入門四檔,用人話教你react-redux,理解redux架構(gòu),以及運(yùn)用在react中。學(xué)完這一章,你就可以開始自己的react項(xiàng)目了。 之前在思否看到過(guò)某個(gè)大神的redux搭建 忘記了大神的名字 這里只記得內(nèi)容了 憑借記憶和當(dāng)時(shí)的學(xué)習(xí)路線寫下本文 隔空感謝 本人學(xué)習(xí)react-redux的時(shí)候遇到了很多坎,特別是不理解為什么這么用,這是什么東西,用來(lái)做什么。加上各種名詞讓人...
摘要:袁鳴把價(jià)格數(shù)量一一進(jìn)行記錄,做了質(zhì)檢記錄合格后辦理了入庫(kù)放入冰箱。但這回家宴與上次的家宴有什么不一樣嗎袁鳴首先把做每道菜的整個(gè)過(guò)程,用什么資源物料多長(zhǎng)時(shí)間邏輯關(guān)系等等都分別錄入到模塊中。 此文已由作者王攀授權(quán)網(wǎng)易云社區(qū)發(fā)布。 歡迎訪問(wèn)網(wǎng)易云社區(qū),了解更多網(wǎng)易技術(shù)產(chǎn)品運(yùn)營(yíng)經(jīng)驗(yàn)。 引言: 目前我們團(tuán)隊(duì)在做的供應(yīng)鏈協(xié)同決策系統(tǒng)(簡(jiǎn)稱河洛,取河洛交匯,河圖洛書之意),定位相當(dāng)于一個(gè)計(jì)劃、控制與...
摘要:隨著以服務(wù)器端的桌面端的和原生移動(dòng)端為代表的全棧迅猛發(fā)展,真正生產(chǎn)環(huán)境中的前端技術(shù)全棧化已經(jīng)逐漸變?yōu)榭赡堋2贿^(guò)在一段時(shí)間之內(nèi),還是會(huì)繼續(xù)向前沖。在剛剛結(jié)束的大會(huì)上,的作者宣布成為的技術(shù)顧問(wèn)。 隨著以服務(wù)器端的NodeJS、桌面端的Electron和原生移動(dòng)端React Native為代表的全棧JS迅猛發(fā)展,真正生產(chǎn)環(huán)境中的JS/前端技術(shù)全棧化已經(jīng)逐漸變?yōu)榭赡堋1M管在前端以外的領(lǐng)域里,J...
摘要:隨著以服務(wù)器端的桌面端的和原生移動(dòng)端為代表的全棧迅猛發(fā)展,真正生產(chǎn)環(huán)境中的前端技術(shù)全棧化已經(jīng)逐漸變?yōu)榭赡堋2贿^(guò)在一段時(shí)間之內(nèi),還是會(huì)繼續(xù)向前沖。在剛剛結(jié)束的大會(huì)上,的作者宣布成為的技術(shù)顧問(wèn)。 隨著以服務(wù)器端的NodeJS、桌面端的Electron和原生移動(dòng)端React Native為代表的全棧JS迅猛發(fā)展,真正生產(chǎn)環(huán)境中的JS/前端技術(shù)全棧化已經(jīng)逐漸變?yōu)榭赡堋1M管在前端以外的領(lǐng)域里,J...
摘要:隨著以服務(wù)器端的桌面端的和原生移動(dòng)端為代表的全棧迅猛發(fā)展,真正生產(chǎn)環(huán)境中的前端技術(shù)全棧化已經(jīng)逐漸變?yōu)榭赡堋2贿^(guò)在一段時(shí)間之內(nèi),還是會(huì)繼續(xù)向前沖。在剛剛結(jié)束的大會(huì)上,的作者宣布成為的技術(shù)顧問(wèn)。 隨著以服務(wù)器端的NodeJS、桌面端的Electron和原生移動(dòng)端React Native為代表的全棧JS迅猛發(fā)展,真正生產(chǎn)環(huán)境中的JS/前端技術(shù)全棧化已經(jīng)逐漸變?yōu)榭赡堋1M管在前端以外的領(lǐng)域里,J...
閱讀 3061·2021-10-27 14:16
閱讀 2879·2021-09-24 10:33
閱讀 2285·2021-09-23 11:21
閱讀 3229·2021-09-22 15:14
閱讀 812·2019-08-30 15:55
閱讀 1676·2019-08-30 15:53
閱讀 1741·2019-08-29 11:14
閱讀 2190·2019-08-28 18:11