Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
µ¥Ò³Ó¦ÓõÄÊý¾ÝÁ÷·½°¸Ì½Ë÷
 
×÷ÕߣºÐì·É À´Ô´£ºÍøÂç·¢²¼ÓÚ£º2017-4-28
  2035  次浏览      27
 

´ó¼ÒºÃ£¬ÏÖÔÚÊÇ2017Äê4Ô¡£¹ýÈ¥µÄ3ÄêÀǰ¶Ë¿ª·¢ÁìÓò¿Éν·çÆðÔÆÓ¿£¬¸ï¹Ê¶¦Ð¡£³ýÁË¿ª·¢ÓïÑÔµÄÓï·¨ÔöÇ¿ºÍ¹¤¾ßÌåϵµÄÌáÉýÖ®Í⣬´ó²¿·ÖÈË¿ªÊ¼Ï°¹ß¼¸¼þÊ£º

×é¼þ»¯

MDV£¨Model Driven View£©

Ëùν×é¼þ»¯£¬ºÜÈÝÒ×Àí½â£¬°ÑÊÓͼ°´ÕÕ¹¦ÄÜ£¬ÇзÖΪÈô¸É»ù±¾µ¥Ôª£¬ËùµÃµÄ¶«Î÷¾Í¿ÉÒÔ³ÆÎª×é¼þ£¬¶ø×é¼þÓÖ¿ÉÒÔÒ»¼¶Ò»¼¶×éºÏ¶ø³É¸´ºÏ×é¼þ£¬´Ó¶øÔÚÕû¸öÓ¦ÓõĹæÄ£ÉÏ£¬ÐγÉÒ»¿Ãµ¹ÖõÄ×é¼þÊ÷¡£ÕâÖÖ·½·¨ÂÛÀúÊ·¾ÃÔ¶£¬ÆäʵÏÖ·½Ê½»òÓÐè¤ÁÁ£¬ÀíÄîÔò´óͬСÒì¡£

¶øMDV£¬ÔòÊǶԺܶàµÍ¼¶DOM²Ù×÷µÄ¼ò»¯£¬°Ñ¶ÔDOMµÄÊÖ¶¯ÐÞ¸ÄÆÁ±ÎÁË£¬Í¨¹ý´ÓÊý¾Ýµ½ÊÓͼµÄÒ»¸öÓ³Éä¹ØÏµ£¬´ïµ½ÁËÖ»Òª²Ù×÷Êý¾Ý£¬¾ÍÄܸıäÊÓͼµÄЧ¹û¡£

Model-Driven-View

¸ø¶¨Ò»¸öÊý¾ÝÄ£ÐÍ£¬¿ÉÒԵõ½¶ÔÓ¦µÄµÄÊÓͼ£¬ÕâÒ»¹ý³Ì¿ÉÒÔ±í´ïΪ£º

V = f(M)

ÆäÖеÄf¾ÍÊÇ´ÓModelµ½ViewµÄÓ³Éä¹ØÏµ£¬ÔÚ²»Í¬µÄ¿ò¼ÜÖУ¬ÊµÏÖ·½Ê½ÓвîÒ죬ÕûÌåÀíÄîÔòÊÇÀàËÆµÄ¡£

µ±Êý¾ÝÄ£ÐͲúÉú±ä»¯µÄʱºò£¬Æä¶ÔÓ¦µÄÊÓͼҲ»áËæÖ®±ä»¯£º

V + ¦¤V = f(M + ¦¤M)

ÁíÍâÒ»¸ö·½Ã棬Èç¹û´Ó±ä¸üµÄ½Ç¶ÈÈ¥½â¶ÁModel£¬Êý¾ÝÄ£ÐͲ»ÊÇÎÞÔµÎ޹ʱ仯µÄ£¬ËüÊÇÓÉij¸ö²Ù×÷ÒýÆðµÄ£¬ÎÒÃÇÒ²¿ÉÒԵóöÁíÍâÒ»¸ö±í´ïʽ£º

¦¤M = perform(action)

°Ñÿ´ÎµÄ±ä¸ü×ÛºÏÆðÀ´£¬¿ÉÒԵõ½¶ÔÕû¸öÓ¦ÓÃ״̬µÄ±í´ï£º

state := actions.reduce(reducer, initState)

Õâ¸ö±í´ïʽµÄº¬ÒåÊÇ£ºÔÚ³õʼ״̬ÉÏ£¬ÒÀ´Îµþ¼ÓºóÐøµÄ±ä¸ü£¬ËùµÃµÄ¾ÍÊǵ±Ç°×´Ì¬¡£Õâ¾ÍÊǵ±Ç°×îÁ÷ÐеÄÊý¾ÝÁ÷·½°¸ReduxµÄºËÐÄÀíÄî¡£

´ÓÕûÌåÀ´Ëµ£¬Ê¹ÓÃRedux£¬Ï൱ÓÚ°ÑÕû¸öÓ¦Óö¼ÊµÏÖΪÃüÁîģʽ£¬Ò»Çб䶯¶¼ÓÉÃüÁîÇý¶¯¡£

Reactive Programming ¿â¼ò½é

ÔÚ´«Í³µÄ±à³Ìʵ¼ùÖУ¬ÎÒÃÇ¿ÉÒÔ£º

¸´ÓÃÒ»ÖÖÊý¾Ý

¸´ÓÃÒ»¸öº¯Êý

¸´ÓÃÒ»×éÊý¾ÝºÍº¯ÊýµÄ¼¯ºÏ

µ«ÊÇ£¬ºÜÄÑ×öµ½£ºÌṩһÖÖ»á³ÖÐø±ä»¯µÄÊý¾ÝÈÃÆäËûÄ£¿é¸´Óá£

¶øÒ»Ð©»ùÓÚReactive ProgrammingµÄ¿â¿ÉÒÔÌṩһÖÖÄÜÁ¦£¬°ÑÊý¾Ý°ü×°³É¿É³ÖÐø±ä¸ü¡¢¿É¹Û²âµÄÀàÐÍ£¬¹©ºóÐøÊ¹Óã¬ÕâÖÖ¿â°üÀ¨£ºRxJS£¬xstream£¬most.jsµÈµÈ¡£

¶ÔÊý¾ÝµÄ°ü×°¹ý³ÌÀàËÆÈçÏ£º

const a$ = xs.of(1)
const arr$ = xs.from([1, 2, 3])
const interval$ = xs.periodic(1000)

Õâ¶Î´úÂëÖеÄa$¡¢arr$¡¢interval$¶¼ÊÇÒ»Öֿɹ۲âµÄÊý¾Ý°ü×°£¬Èç¹û¶ÔËüÃǽøÐж©ÔÄ£¬¾Í¿ÉÒÔÊÕµ½ËùÓвúÉúµÄ±ä¸ü¡£

interval$.subscribe(console.log)

ÎÒÃÇ¿ÉÒÔ°ÑÕâÖÖ·â×°½á¹¹ÊÓΪÊý¾Ý¹ÜµÀ£¬ÔÚÕâÖֹܵÀÉÏ£¬¿ÉÒÔÌí¼ÓͳһµÄ´¦Àí¹æÔò£¬ÕâÖÖ¹æÔò»á×÷ÓÃÔڹܵÀÖеÄÿ¸öÊý¾ÝÉÏ£¬²¢ÇÒÐγÉеĹܵÀ£º

const interval$ = xs.periodic(1000)
const result$ = interval$
.filter(num => num % 3)
.map(num => num * 2)

¹ÜµÀ¿É±»Á¬ÐøÆ´½Ó£¬²¢ÐγÉеĹܵÀ¡£

ÐèҪעÒâµÄÊÇ£º

¹ÜµÀÊÇÀÁÖ´Ðеġ£Ò»¸öÆ´½ÓÆðÀ´µÄÊý¾Ý¹ÜµÀ£¬Ö»ÓÐ×îÄ©¶Ë±»¶©ÔĵÄʱºò£¬¸½¼ÓÔڹܵÀÉϵÄËùÓÐÂß¼­²Å»á±»Ö´ÐС£

Ò»°ãÇé¿öÏ£¬¹ÜµÀµÄÖ´Ðйý³Ì¿ÉÒÔ±»¹²Ïí£¬±ÈÈçb$ºÍc$Á½¸ö¹ÜµÀ£¬¶¼´Óa$±äÐεóö£¬ËüÃǾ͹²ÏíÁËa$֮ǰµÄËùÓÐÖ´Ðйý³Ì¡£

Ò²¿ÉÒ԰Ѷà¸ö¹ÜµÀ×éºÏÔÚÒ»ÆðÐγÉеĹܵÀ£º

const priv$ = xs.combine(user$, article$)
.map(arr => {
const [user, article] = arr
return user.isAdmin || article.creator === user.id
})

´ÓÕâ¸ö¹ØÏµÖпÉÒÔ¿´³ö£¬µ±user$»òtask$ÖеÄÊý¾Ý·¢Éú±ä¸üµÄʱºò£¬priv$¶¼»á×Ô¶¯¼ÆËã³ö×îнá¹û¡£

ÔÚÒµÎñ¿ª·¢µÄ¹ý³ÌÖУ¬¿ÉÒÔʹÓÃÊý¾ÝÁ÷µÄÀíÄ°ÑºÜ¶à¶«Î÷Ìá¸ßÒ»¸ö³éÏóµÈ¼¶£º

const data$ = xs.fromPromise(service(params))
.map(data => ({ loading: false, data }))
.replaceError(error => xs.of({ loading: false, error }))
.startWith({
loading: true,
error: null,
})

±ÈÈçÉÏÃæÕâ¸öÀý×Ó£¬Í³Ò»´¦ÀíÁËÒ»¸öÆÕͨÇëÇó¹ý³ÌÖеÄÈýÖÖ״̬£ºÇëÇóǰ¡¢³É¹¦¡¢Òì³££¬²¢ÇÒ°ÑËüÃǵÄÊý¾Ý£ºloading¡¢Õý³£Êý¾Ý¡¢Òì³£Êý¾Ý¶¼Í³Ò»³ÉÒ»ÖÖ£¬ÊÓͼֱ½Ó¶©ÔÄ´¦Àí¾ÍÐÐÁË¡£

¸ß¶È³éÏóµÄÊý¾ÝÀ´Ô´

ºÜ¶àʱºò£¬ÎÒÃǽøÐÐÒµÎñ¿ª·¢£¬¶¼ÊÇÔÚÒ»ÖֱȽϵͲã´ÎµÄ³éÏóά¶ÈÉÏ£¬ÔڵͲã³éÏóÉÏ£¬´æÔÚ×ÅÌ«¶àµÄÈßÓà¹ý³Ì¡£Èç¹ûÄܹ»¶ÔÊý¾ÝµÄÀ´Ô´ºÍÈ¥Ïò×öһЩ¹éÄÉ»áÔõÑùÄØ£¿

±ÈÈç˵£¬´ÓʵÌåµÄ½Ç¶È£¬ºÜ¿ÉÄÜÒ»·ÝÊý¾Ý³õʼ״̬Óжà¸öÀ´Ô´£º

Ó¦ÓõÄĬÈÏÅäÖÃ

HTTPÇëÇó

±¾µØ´æ´¢

...µÈµÈ

Ò²ºÜ¿ÉÄÜÓжà¸öʼþ¶¼ÊÇÔÚÐÞ¸Äͬһ¸ö¶«Î÷£º

Óû§´ÓÊÓͼ·¢ÆðµÄ²Ù×÷

À´×ÔWebSocketµÄÍÆËÍÏûÏ¢

À´×ÔWorkerµÄ´¦ÀíÏûÏ¢

À´×ÔÆäËü´°ÌåµÄpostMessageµ÷ÓÃ

...µÈµÈ

Èç¹û²»×ö¹éÄÉ£¬¿ÉÄÜ»áд³ö°üº¬ÒÔÉϸ÷ÖÖ¶«Î÷µÄÂß¼­×éºÏ¡£Èô¸É¸öÀàËÆµÄ²Ù×÷£¬ÔÚ¹ýÂ˵ô¶îÍâÐÅÏ¢Ö®ºó£¬¿ÉÄܶ¼ÊÇÒ»ÑùµÄ¡£´ÓÓ¦ÓÃ״̬µÄ½Ç¶È£¬ÎÒÃDz»»áÐèÒª¹ØÐÄÒ»¸öÊý¾Ý¾¿¾¹ÊÇ´ÓÄÄÀïÀ´µÄ£¬Ò²²»»áÐèÒª¹ØÐÄÊÇͨ¹ýʲô¶«Î÷·¢ÆðµÄÐ޸ġ£

Óô«Í³µÄReduxд·¨£¬¿ÉÄÜ»áÌáÈ¡³öһЩ¹«¹²·½·¨£º

const changeTodo = todo => {
dispatch({type: 'updateTodo', payload: todo})
}

const changefromDOMEvent = () => {
const todo = formState
changeTodo(todo)
}

const changefromWebSocket = () => {
const todo = fromWS
changeTodo(todo)
}

»ùÓÚ·½·¨µ÷ÓõÄÂß¼­²»ÄܺܺõØÕ¹Ê¾Ò»·ÝÊý¾ÝµÄÉúÃüÖÜÆÚ£¬Ëü¿ÉÄÜÓÐÄÄЩÀ´Ô´£¿¿ÉÄܱ»Ê²Ã´Ð޸ģ¿ËüÊǾ­¹ý¼¸Ç§ÄêÔõÑùµÄÐÁ¿àÐÞÁ¶Ö®ºó²ÅÄܹ»»¯³ÉÈËÐΣ¬¸úÄã×øÔÚÒ»ÕÅ×À×ÓÉϺȿ§·È£¿

ÎÒÃÇ¿ÉÒÔ½èÖúRxJS»òÕßxstreamÕâÑùµÄ¿â£¬ÒÔÊý¾Ý¹ÜµÀµÄÀíÄ°ÑÕâЩ¶«Î÷¸ü¼ÓÖ±¹ÛµØ×éÖ¯ÔÚÒ»Æð£º

³õʼ״̬À´Ô´

const fromInitState$ = xs.of(todo)
const fromLocalStorage$ = xs.of(getTodoFromLS())

// initState
const init$ = xs
.merge(
fromInitState$,
fromLocalStorage$
)
.filter(todo => !todo)
.startWith({})

Êý¾Ý±ä¸ü¹ý³ÌµÄͳһ

const changeFromHTTP$ = xs.fromPromise(getTodo())
.map(result => result.data)
const changeFromDOMEvent$ = xs
.fromEvent($('.btn', 'click'))
.map(evt => evt.data)
const changeFromWebSocket$ = xs
.fromEvent(ws, 'message')
.map(evt => evt.data)

// ºÏ²¢ËùÓбä¸üÀ´Ô´
const changes$ = xs
.merge(
changeFromHTTP$,
changeFromDOMEvent$,
changeFromWebSocket$
)

ÔÚÕâÑùµÄ»úÖÆÀÎÒÃÇ¿ÉÒÔºÜÇå³þµØ¿´µ½Ò»¿éÊý¾ÝµÄÀ´ÁúÈ¥Âö£¬Ëü×î³õÊÇÄÄÀïÀ´µÄ£¬ºóÀ´¿ÉÄܻᱻ˭Ð޸Ĺý¡£ËùÓÐÕâÑùµÄÊý¾Ý¶¼·ÅÖÃÔڹܵÀÖУ¬³ýÁËÖ¸¶¨µÄÈë¿Ú£¬²»»áÓÐÆäËû¶«Î÷Äܹ»ÐÞ¸ÄÕâЩÊý¾Ý£¬ÊÓͼ¿ÉÒԺܰ²È«µØ¶©ÔÄËûÃÇ¡£

»ùÓÚReactiveÀíÄîµÄÕâЩÊý¾ÝÁ÷¿â£¬Ò»°ãÊÇûÓÐÕë¶ÔÒµÎñ¿ª·¢µÄÇ¿Ô¼ÊøµÄ£¬Ò²ÒÔÖ±½Ó¶©ÔIJ¢ÉèÖÃ×é¼þ״̬£¬Ò²¿ÉÒÔÄÃËü°´ÕÕReduxµÄÀíÄîÀ´Ê¹Ó㬷á¼óÓÉÈË¡£

¼òµ¥µÄʹÓÃ

changes$.subscribe(({ payload }) => {
xxx.setState({ todo: payload })
})

ÀàËÆReduxµÄʹÓ÷½Ê½

const updateActions$ = changes$
.map(todo => ({type: 'updateTodo', payload: todo}))

const todo$ = changeActions$
.fold((state, action) => {
const { payload } = action
return {...state, ...payload}
}, initState)

×é¼þÓëÍâÖÃ״̬

ÎÒÃÇÇ°ÃæÌáµ½£¬×é¼þÊ÷ÊÇÒ»¸öÊ÷Ðνṹ¡£ÀíÏëÖеÄ×é¼þ»¯£¬ÊÇËùÓÐÊÓͼ״̬ȫ²¿ÄÚÖÃÔÚ×é¼þÖУ¬Ò»¼¶Ò»¼¶´«µÝ¡£Ö»ÓÐÕâÑù£¬²ÅÄÜ´ïµ½×é¼þµÄ×î¼Ñ¿É¸´ÓÃ״̬£¬²¢ÇÒ£¬×é¼þ¿ÉÒÔ·ÅÐİÑ×Ô¼º¸Ã×öµÄÊÂÇé¶¼×öÁË¡£

µ«ÊÂʵÉÏ£¬×é¼þÊ÷µÄ²ã¼¶¿ÉÄܺܶ࣬Õâ»áµ¼Ö´«µÝ²ã¼¶ºÜ¶à£¬ºÜ·±Ëö£¬¶øÇÒ£¬´æÔÚÒ»¸ö¾­µäÎÊÌ⣬ÄǾÍÊÇÐÖµÜ×é¼þ£¬»òÕßÊÇλÓÚ×é¼þÊ÷µÄ²»Í¬Ê÷Ö¦ÉϵÄ×é¼þÖ®¼äµÄͨÐźÜÂé·³£¬±ØÐëͨ¹ý¹²Í¬µÄ×î½üµÄ׿ÏȽڵãȥת·¢¡£

ÏñReduxÕâÑùµÄ»úÖÆ£¬°Ñ״̬µÄ³ÖÓк͸üÐÂÍâÖã¬È»ºóͨ¹ýconnectÕâÑùµÄ·½·¨£¬È¥°ÑÌØ¶¨×é¼þËùÐèµÄÍⲿ״̬´ÓpropsÉèÖýøÈ¥£¬µ«Ëü²»½ö½öÊÇÒ»¸öת·¢Æ÷¡£

ÎÒÃÇ¿ÉÒÔ¿´µ½ÈçÏÂÊÂʵ£º

ת·¢Æ÷ÔÚ×é¼þÊ÷Ö®Íâ

²¿·ÖÊý¾ÝÔÚ×é¼þÊ÷Ö®Íâ

¶ÔÕⲿ·ÖÊý¾ÝµÄÐ޸Ĺý³ÌÔÚ×é¼þÊ÷Ö®Íâ

ÐÞ¸ÄÍêÊý¾ÝÖ®ºó£¬Í¨Öª×é¼þÊ÷¸üÐÂ

ËùÒÔ£º

×é¼þ¿ÉÒÔͨ¹ýÖÐתÆ÷ÐÞ¸ÄÆäËû×é¼þµÄ״̬

×é¼þ¿ÉÒÔͨ¹ýÖÐתÆ÷ÐÞ¸Ä×ÔÉíµÄ״̬

×é¼þ¿ÉÒÔͨ¹ýÖÐתÆ÷ÐÞ¸ÄÈ«¾ÖµÄÆäËû״̬

ÕâÑù¿´À´£¬¿ÉÒÔͨ¹ýÖÐתÆ÷ÐÞ¸ÄÓ¦ÓÃÖеÄÒ»ÇÐ״̬¡£ÄÇô£¬Èç¹ûËùÓÐ״̬¶¼¿ÉÒÔͨ¹ýÖÐתÆ÷Ð޸ģ¬ÊÇ·ñÒâζ×Ŷ¼Ó¦µ±Í¨¹ýËüÐ޸ģ¿

Õâ¸öÎÊÌâºÜ´ó³Ì¶ÈÉϵȼÛÓÚ£º

×é¼þÊÇ·ñÓ¦µ±ÓµÓÐ×Ô¼ºµÄÄÚ²¿×´Ì¬£¿

ÎÒÃÇ¿ÉÄÜ»áÓÐÈçϵÄÑ¡Ôñ£º

Ò»ÇÐ״̬ÍâÖã¬×é¼þ²»¹ÜÀí×Ô¼º×´Ì¬

²¿·ÖÄÚÖã¬ÓÉ×é¼þ×Ô¼º¹ÜÀí£¬ÁíÍâһЩÓÉÈ«¾ÖStore¹ÜÀí

ÕâÁ½ÖÖ·½Ê½£¬ÔÚ´«Í³Èí¼þ¿ª·¢ÁìÓò·Ö±ð³ÆÎªÆ¶Ñª×é¼þ¡¢³äѪ×é¼þ£¬ËüÃǵIJî±ðÊÇ£º×é¼þ¾¿¾¹ÊÇ´¿Õ¹Ê¾£¬»¹ÊÇ´øÒ»Ð©Âß¼­¡£

Ò²¿ÉÒÔÄÃÒÏȺºÍÈËȺÀ´ÐÎÈÝÕâÁ½ÖÖ×é¼þʵ¼ù¡£µ¥¸öÂìÒϵÄÖÇÄ̶ܳȺܵͣ¬µ«Ëü¿ÉÒÔ½ÓÊÜÒÏÍõµÄÖ¸ÁîÈ¥×öijЩÊÂÇ飬ËùÓеÄÂé·³ÊÂÇé¶¼¼¯ÖÐÔÚÉϲ㣬¾ö²ß²ãµÄÊÂÎñ·Ç³£·±Ëö¡£¶øÈËÀàÔò²»Í¬£¬Ã¿¸öÈ˶¼ÓÐ×Ô¼ºµÄ˼¿¼ºÍÖ´ÐÐÄÜÁ¦£¬Ò»¸ö¹ÜÀíÓÐÐòµÄÌåϵÖУ¬¹ÜÀíÕßÖ»Ðè¾ö¶¨ËûºÍ×Ô¼ºÖ±½ÓÏÂÊôËùÐèÒª×öµÄÊÂÇé¾Í¿ÉÒÔÁË¡£

ÔÚReactÌåϵÖУ¬´¿Õ¹Ê¾×é¼þ¿É±»¼ò»¯ÎªÕâÑùµÄÐÎʽ£º

const ComponentA = (props) => {
return (<div>{props.data}</div>)
}

ÏÔ¶øÒ×¼û£¬ÕâÖÖ×é¼þµÄÓÅÊÆÔÚÓÚËüµÄչʾ½á¹ûÖ»¸úÊäÈëÊý¾ÝÓйأ¬ËùÓÐ״̬ÍâÖã¬Òò´Ë£¬ÔÚÈÈÌæ»»µÈ·½Ã棬¿ÉÒÔ×öµ½¼«Ö¡£

È»¶ø£¬Ò»µ©Õâ¸ö×é¼þ¸´ÔÓÆðÀ´£¬×Ô´ø½»»¥£¬¿ÉÄܾÍÐèÒªÔÚʼþ¡¢ÉúÃüÖÜÆÚÉÏ×öÎÄÕ£¬Ãâ²»ÁË»áÐèҪһЩÖмä״̬À´±í´ï×é¼þ×ÔÉíµÄÐÎ̬¡£

ÎÒÃǵ±È»¿ÉÒÔ°ÑÕâÖÖ״̬ҲÍâÖ㬵«Õâô×öÓм¸¸öÎÊÌ⣺

ÕâÑùµÄ״ֻ̬¸úij×é¼þ×Ô¼ºÓйأ¬·Å³öÈ¥µ½È«¾ÖStore£¬»áÔö¼ÓStoreµÄ²»±ØÒªµÄ¸´ÔÓ¶È

×é¼þµÄ×ÔÉíÐÎ̬״̬±»ÍâÖ㬽«µ¼ÖÂ×é¼þÓë״̬µÄ¾àÀë±äÔ¶£¬´Ó¶ø¶ÔÕâЩ״̬µÄ¶Áд±äµÃ±ÈÔ­ÏÈ·±Ëö

´ø½»»¥µÄ×é¼þ£¬ÎÞ·¨¶ÀÁ¢¡¢ÍêÕûµØÃèÊö×ÔÉíµÄÐÐΪ£¬±ØÐë½èÖúÍⲿ¹ÜÀíÆ÷

Èç¹ûÊÇÒ»ÖÖµ¥¶ÀÌṩµÄ×é¼þ¿â£¬±ÈÈçÏñAnt DesignÕâÑùµÄ£¬È´ÒªÒÀÀµÒ»¸öÍⲿµÄ״̬¹ÜÀíÆ÷£¬ÕâÊǺܲ»ºÏÊʵģ¬Ëü»áµ¼ÖÂ×é¼þ¿â´øÓÐÇãÏòÐÔ£¬´Ó¶ø¶ÔʹÓÃÕßÔì³ÉÀ§ÈÅ¡£

×ܵÄÀ´Ëµ£¬×´Ì¬È«ÍâÖã¬×é¼þÍË»¯ÎªÆ¶Ñª×é¼þÕâÖÖʵ¼ù£¬¿ÉÒԵõ½²»Éٺô¦£¬µ«´ú¼ÛÊDZȽϴóµÄ¡£

ÔÚYou might not need ReduxÕâÆªÎÄÕÂÖУ¬ReduxµÄ×÷ÕßDan AbramovÌáµ½£º

Local State is Fine.

Òò´Ë£¬ÎÒÃǾͿÉÄÜ»áÃæÁÙÒ»¸öÞÏÞεÄ×´¿ö£¬Ôڴ󲿷Öʵ¼ùÖУº

Ò»¸ö×é¼þµÄ״̬£¬¿ÉÄÜÒ»°ëÔÚ×é¼þÄÚ¹ÜÀí£¬Ò»°ëÔÚÈ«¾ÖµÄStoreÀï

ÒÔReactΪÀý£¬´óÖÂÊÇÕâÑùÒ»¸ö×´¿ö£º

constructor(props) {
super(props)
this.state = { b: 1 }
}

render(props) {
const a = this.state.b + props.c;
return (<div>{a}</div>)
}

ÎÒÃÇ¿´µ½£¬ÔÚrenderÀïÃæ£¬ÐèÒªºÏ²¢stateºÍpropsµÄÊý¾Ý£¬µ«ÊÇÔÚÕâÀï×öÕâ¸öÊÂÇ飬ÊÇÆÆ»µÁËrenderº¯ÊýµÄ´¿½àÐԵġ£¿ÉÊÇ£¬³ýÁËÕâÀ±ðµÄµØ·½Ò²²»Ì«ÊʺÏ×öÕâÖֺϲ¢£¬Ôõô°ìÄØ£¿

ËùÒÔ£¬ÎÒÃÇÐèÒªÒ»ÖÖ»úÖÆ£¬Äܹ»°Ñ±¾µØ×´Ì¬ºÍpropsÔÚrenderÖ®ÍâͳһÆðÀ´£¬Õâ¿ÉÄܾÍÊǺܶàʵ¼ùÕßÇãÏòÓڰѱ¾µØ×´Ì¬Ò²ÍâÖõÄ×îÖØÒªÔ­Òò¡£

ÔÚReact + ReduxµÄʵ¼ùÖУ¬Í¨³£»áʹÓÃconnect¶ÔÊÓͼ×é¼þ°ü×°Ò»²ã£¬±ä³ÉÒ»ÖÖ½Ð×öÈÝÆ÷×é¼þµÄ¶«Î÷£¬Õâ¸öconnectËù×öµÄÊÂÇé¾ÍÊǰÑÈ«¾Ö״̬ӳÉäµ½×é¼þµÄpropsÖС£

ÄÇô£¬¿¼ÂÇÈçÏ´úÂ룺

const mapStateToProps = (state: { a }) => {
return { a }
}

// const localState = { b: 1 }
// const mapLocalStateToProps = localState => localState

const ComponentA = (props) => {
const { a, b } = props
const c = a + b
return (<div>{ c }</div>)
}

return connect(mapStateToProps/*, mapLocalStateToProps*/)(ComponentA)

ÎÒÃÇÊÇ·ñ¿ÉÒÔ°ÑÒ»¸ö×é¼þµÄÄÚ²¿×´Ì¬ÍâÖõ½±»×¢Ê͵ôµÄÕâ¸öλÖã¬È»ºóÒ²connect½øÀ´ÄØ£¿Õâ¶Î´úÂëÆäʵÊDz»Æð×÷Óõģ¬ÒòΪ¶ÔlocalStateµÄ¸Ä±ä²»»á±»¼ì²âµ½£¬ËùÒÔ×é¼þ²»»áˢС£

ÎÒÃÇÏÈ̽Ë÷ÕâÖÖģʽÊÇ·ñ¿ÉÐУ¬È»ºóÔÙÀ´¿¼ÂÇʵÏÖµÄÎÊÌâ¡£

MVI¼Ü¹¹

ÔÚPlug and Play All Your Observable Streams With Cycle.jsÕâÆªÎÄÕÂÖУ¬ÎÒÃÇ¿ÉÒÔ¿´µ½Ò»×éÀíÄ

Ò»Çж¼ÊÇʼþÔ´

ʹÓÃReactiveµÄÀíÄî¹¹½¨³ÌÐòµÄ¹Ç¼Ü

ʹÓÃsinkÀ´¶¨ÒåÓ¦ÓõÄÂß¼­

ʹÓÃdriverÀ´¸ôÀëÓи±×÷ÓõÄÐÐΪ£¨ÍøÂçÇëÇó¡¢DOMäÖȾ£©

»ùÓÚÕâÌ×ÀíÄ±àд´úÂëµÄ·½Ê½¿ÉÒÔ±äµÃºÜ¼ò½àÁ÷³©£º

´ÓdriverÖлñÈ¡action

°ÑactionÓ³Éä³ÉÊý¾ÝÁ÷

´¦ÀíÊý¾ÝÁ÷£¬²¢ÇÒäÖȾ³É½çÃæ

´Ó½çÃæµÄʼþÖУ¬ÅÉ·¢actionÈ¥½øÐкóÐøÊÂÏîµÄ´¦Àí

ÔÚCycleJSµÄÀíÄîÖУ¬ÕâÖÖģʽ½Ð×öMVI£¨Model View Intent£©¡£ÔÚÕâÌ×ÀíÄîÖУ¬ÎÒÃǵÄÓ¦ÓÿÉÒÔ·ÖΪÈý¸ö²¿·Ö£º

Intent£¬¸ºÔð´ÓÍⲿµÄÊäÈëÖУ¬ÌáÈ¡³öËùÐèÐÅÏ¢

Model£¬¸ºÔð´ÓIntentÉú³ÉÊÓͼչʾËùÐèµÄÊý¾Ý

View£¬¸ºÔð¸ù¾ÝÊÓͼÊý¾ÝäÖȾÊÓͼ

ÕûÌå½á¹¹¿ÉÒÔÕâÑùÃèÊö£º

App := View(Model(Intent({ DOM, Http, WebSocket })))

¶Ô±ÈReduxÕâÑùµÄ»úÖÆ£¬ËüµÄ²îÒìÔÚÓÚ£º

Intentʵ¼ÊÉÏ×öµÄÊÇactionÖ´Ðйý³ÌµÄ¸ß¼¶³éÏó£¬ÌáÈ¡Á˱ØÒªµÄÐÅÏ¢

Model×öµÄÊÇreducerµÄÊÂÇ飬°ÑactionµÄÐÅϢת»»Ö®ºóºÏ²¢Îª×´Ì¬¶ÔÏó

View¸úÆäËû¿ò¼ÜÃ»Ê²Ã´Çø±ð£¬´Ó״̬¶ÔÏóäÖȾ³ÉÊÓͼ¡£

´ËÍ⣬ÔÚCycleJSÖУ¬ViewÊÇ´¿Õ¹Ê¾£¬Á¬Ê¼þ¼àÌýÒ²²»×ö£¬Õⲿ·Ö¼àÌýµÄ¹¤×÷·ÅÔÚIntentÖÐÈ¥×ö¡£

const model = (a$, b$) => {
return xs.combine(a$, b$)
}

const view = (state$) => {
return state$.map(({ a, b }) => {
const c = a + b;
return h2('c is ' + c)
})
}

ÎÒÃÇ¿ÉÒÔ´ÓÖз¢¾òÕâôһЩ¶«Î÷£º

View»¹ÊÇ´¿äÖȾ£¬½ÓÊܵÄΨһ²ÎÊý¾ÍÊÇÒ»¸ö±í´ïÊÓͼ״̬µÄÊý¾ÝÁ÷

ModelµÄ·µ»Ø½á¹û¾ÍÊÇÉÏÃæÄǸöÁ÷£¬²»·ÖÄÚÍâ״̬£¬È«²¿ºÏ²¢ÆðÀ´

ModelËùºÏ²¢µÄ¶«Î÷µÄÀ´Ô´£¬ÊÇ´ÓIntentÖÐÀ´µÄ

¶ÔÎÒÃÇÀ´Ëµ£¬ÕâÀïÃæ×î´ó¹Ø¼üÔÚÓÚ£ºËùÓж«Î÷µÄÊäÈëÊä³ö¶¼ÊÇÊý¾ÝÁ÷£¬ÉõÖÁÁ¬ÊÓͼ½ÓÊܵIJÎÊý¡¢»¹ÓÐËüµÄäÖȾ½á¹ûÒ²ÊÇÒ»¸öÁ÷£¡°ÂÃØ¾ÍÔÚÕâÀï¡£

Òò´Ë£¬ÎÒÃÇÖ»ÐèÔÚ°Ñ´ý´«ÈëÊÓͼµÄpropsÓëÊÓͼµÄstateÒÔÁ÷µÄ·½Ê½ºÏ²¢£¬Ö±½Ó°ÑºÏ²¢Ö®ºóµÄÁ÷µÄ½á¹û´«ÈëÊÓͼ×é¼þ£¬¾ÍÄÜ´ïµ½ÎÒÃÇÔÚÉÏÒ»½ÚÖÐÌá³öµÄÐèÇó¡£

×é¼þ»¯Óë·ÖÐÎ

ÎÒÃÇ֮ǰÌáµ½¹ýÒ»µã£¬ÔÚÒ»¸öÓ¦ÓÃÖУ¬×é¼þÊÇÐγɵ¹ÖõÄÊ÷ÐνṹµÄ¡£µ±×é¼þÊ÷ÉϵÄijһ¿éÔ½À´Ô½¸´ÔÓ£¬ÎÒÃǾͰÑËüÔٲ𿪣¬ÑÓÉì³öеÄÊ÷Ö¦ºÍÒ¶×Ó£¬Õâ¸ö¹ý³Ì£¬Óë·ÖÐÎÓÐÒìÇúͬ¹¤Ö®Ãî¡£

È»¶ø£¬ÒòΪȫ¾Ö״̬ºÍ±¾µØ×´Ì¬µÄ·ÖÀ룬µ¼ÖÂÿһ´Î·ÖÐΣ¬ÎÒÃǶ¼Òª¼æ¹Ë±¾×é¼þ¡¢Ï¼¶×é¼þ¡¢È«¾Ö״̬¡¢±¾µØ×´Ì¬£¬ÔÚËüÃÇÖ®¼ä×÷һЩȨºâ£¬ÕâÊÇÒ»¸öºÜÂé·³µÄ¹ý³Ì¡£ÔÚReactµÄÖ÷Á÷ʵ¼ùÖУ¬Ò»°ã¿ÉÒÔÀûÓÃconnectÕâÑùµÄ¸ß½×º¯Êý£¬°ÑÈ«¾Ö״̬ӳÉä½ø×é¼þµÄprops£¬×ª»¯Îª±¾µØ×´Ì¬¡£

ÉÏÒ»½ÚÌá¼°µÄMVI½á¹¹£¬²»½ö½öÄܹ»ÃèÊöÒ»¸öÓ¦ÓõÄÖ´Ðйý³Ì£¬»¹¿ÉÒÔµ¥¶ÀÃèÊöÒ»¸ö×é¼þµÄÖ´Ðйý³Ì¡£

Component := View(Model(Intent({ DOM, Http, WebSocket })))

ËùÒÔ£¬´ÓÕûÌåÀ´Àí½âÎÒÃǵÄÓ¦Ó㬾ÍÊÇÕâÑùÒ»¸ö¹ØÏµ£º

 APP [ View <-- Model <-- Intent ]
|
------------------------------------------------
| |
ComponentA [ ViewA <-- ModelA <-- IntentA ] ComponentB

ÕâÑùÒ»Ö±·ÖÐÎÏÂÈ¥£¬Ã¿Ò»¼¶×é¼þ¶¼¿ÉÒÔÓµÓÐ×Ô¼ºµÄView¡¢Model¡¢Intent¡£

״̬µÄ±ä¸ü¹ý³Ì

ÔÚÄ£ÐÍÇý¶¯ÊÓͼÕâ¸öÀíÄîÏ£¬ÊÓͼʼÖÕ»áÊǵ÷ÓÃÁ´µÄ×îºóÒ»¶Î£¬ËüµÄÖ°Ôð¾ÍÊÇÏû·ÑÒѾ­¼ÆËãºÃµÄÊý¾Ý£¬äÖȾ³öÀ´¡£ËùÒÔ£¬´ÓÕâ¸ö½Ç¶È¿´£¬ÎÒÃǵÄÖØµã¹¤×÷ÔÚÓÚÔõô¹ÜÀí״̬£¬°üÀ¨½á¹¹µÄ¶¨ÒåºÍ±ä¸üµÄÁ÷ת¹ý³Ì¡£

ReduxÌṩÁ˶Ô״̬¶¨ÒåºÍ±ä¸ü¹ý³ÌµÄ¹ÜÀí˼·£¬µ«Óв»ÉÙÖµµÃ̽Ìֵĵط½¡£

»ùÓÚ±ê×¼Flux£¯ReduxµÄʵ¼ùÓÐÒ»¸ö¹²Í¬µã£º·±Ëö¡£²úÉúÕâÖÖ·±ËöµÄ×îÖ÷ÒªÔ­ÒòÊÇ£¬ËüÃǶ¼ÊÇÒÔ×Ô¶¨ÒåʼþΪºËÐĵģ¬×Ô¶¨Òåʼþ±¾Éí¾ÍÊÇ·±ËöµÄ¡£ÓÉÓÚÊÕ·¢Ê¼þͨ³£Î»ÓÚÁ½¸öÒÔÉϲ»ÏàͬµÄÄ£¿éÖУ¬²»µÃ²»ÒÔ·â×°µÄʼþ¶ÔÏóΪͨÐÅÔØÌ壬²¢ÇÒ±ØÐëÏÔʽ¶¨ÒåʼþµÄkey£¬·ñÔò½ÓÊÕ·½ÎÞ·¨Ö¸¶¨×Ô¼ºµÄÏìÓ¦¡£

Ò»µ©Õû¸öÓ¦Óö¼ÊÇÒÔ´ËΪ»ùʯ£¬ÆäÖеķ±Ëö³Ì¶È¿ÉÏë¶øÖª£¬ËùÒÔÉçÇø»á´æÔÚһЩ¼ò»¯action´´½¨£¬»òÕßͨ¹ýÔ¼¶¨À´¼õÉÙactionÊÕ·¢Öм价½ÚµÄReduxÖܱߡ£

Èç¹û²»´Ó¸ù±¾É϶ÔʼþÕâÖÖ»úÖÆ½øÐгéÏ󣬾Ͳ»¿ÉÄܳ¹µ×½â¾ö·±ËöµÄÎÊÌ⣬»ùÓÚReactiveÀíÄîµÄÕ⼸¸ö¿âÌìÈ»¾ÍÊÇΪÁË´¦Àí¶Ôʼþ»úÖÆµÄ³éÏó¶ø³öÏֵģ¬ËùÒÔÓÃÔÚÕâÖÖ³¡¾°ÏÂÓÐÆæÐ§£¬ÄܰÑactionµÄÅÉ·¢Óë´¦Àí¹ý³ÌÃèÊöµÃÓÅÑž«Ãî¡£

const updateActions$ = changes$
.map(todo => ({type: 'updateTodo', payload: todo}))

const todo$ = updateActions$
.fold((state, action) => {
const { payload } = action
return {...state, ...payload}
}, initState)

×¢ÒâÒ»¸öÎÊÌ⣬¼ÈÈ»ÎÒÃÇ֮ǰµÃµ½Ò»ÖÖ˼·£¬°ÑÈ«¾Ö״̬ºÍ±¾µØ×´Ì¬·Ö¿ª£¬È»ºóºÏ²¢×¢Èë×é¼þ£¬¾ÍÐèÒª¿¼ÂÇÕâÑùµÄÎÊÌ⣺ÈçºÎ¹ÜÀí±¾µØ×´Ì¬ºÍÈ«¾Ö״̬£¬Ê¹ÓÃÏàͬµÄ·½Ê½È¥¹ÜÀíÂð£¿

ÔÚReduxÌåϵÖУ¬ÎÒÃÇÔÚÐÞ¸ÄÈ«¾Ö״̬µÄʱºò£¬Ê¹ÓÃÖ¸¶¨µÄactionÈ¥ÐÞ¸Ä״̬£¬Ô­ÒòÊÇ񻂿·ÖÄǸöÄĸöactionÐÞ¸ÄstateµÄʲô²¿·Ö£¬ÔõÑùÐ޸ġ£µ«ÊÇ¿¼ÂDZ¾µØ×´Ì¬µÄÇé¿ö£¬Ëü·´Ó³µÄÖ»ÊÇ×é¼þÄÚ²¿µÄÊý¾Ý±ä»¯£¬Ò»°ã¶øÑÔ£¬Æä½á¹¹¸´Ôӳ̶ÈÔ¶Ô¶µÍÓÚÈ«¾Ö״̬£¬¼ÌÐø²ÉÓÃÕâÖÖ·½Ê½µÄ»°²¢²»»®Ëã¡£

ReduxÕâÀà¶«Î÷³öÏֵijõÖÔÖ»ÊÇΪÁËÌṩһÖÖµ¥ÏòÊý¾ÝÁ÷µÄ˼·£¬·Àֹ״̬Ð޸ĵĻìÂÒ¡£µ«ÊÇÔÚ»ùÓÚÊý¾Ý¹ÜµÀµÄÕâЩ¿âÖУ¬Êý¾ÝÌìÈ»¾ÍÊǵ¥ÏòÁ÷¶¯µÄ¡£ÔÚ¸Õ²ÅÄǶδúÂëÀÆäʵactionµÄtypeÊÇûÓÐÒâÒåµÄ£¬Ò»Ö±¾ÍûÓÐÓõ½¡£

ʵ¼ÊÉÏ£¬Õâ¸ö´úÂëÖеÄupdateActions$×ÔÉí¾Í±í´ïÁËupdateTodoµÄº¬Ò壬¶øËüºóÐøµÄfold²Ù×÷£¬Êµ¼ÊÉϾÍÊÇÖ±½ÓÔÚreduce¡£Àí½âÁËÕâÒ»µãÖ®ºó£¬ÎÒÃǾͿÉÒÔд³ö·´Ó³Èô¸ÉÖÖÊý¾Ý±ä¸üµÄºÏ¼¯ÁË£¬Õâ¸öʱºò£¬¿ÉÒÔ¸ù¾Ý²»Í¬µÄactionȥѡÔñ²»Í¬µÄreducer²Ù×÷£º

// ÎÒÃÇ¿ÉÒÔÏȰÑÕâЩactionÈ«²¿mergeÖ®ºóÔÙfold£¬¸úReduxµÄÀíÄîÀàËÆ
const actions = xs.merge(
addActions$,
updateActions$,
deleteActions$
)

const localState$ = actions.fold((state, action) => {
switch(action.type) {
case 'addTodo':
return addTodo(state, action)
case 'updateTodo':
return updateTodo(state, action)
case 'deleteTodo':
return deleteTodo(state, action)
}
}, initState)

ÎÒÃÇ×¢Òâµ½£¬ÕâÀïÊǰÑËùÓÐactionÈ«²¿mergeÁËÖ®ºóÔÙfoldµÄ£¬ÕâÊÇ·ûºÏRedux·½Ê½µÄ×ö·¨¡£ÓÐûÓпÉÄܸ÷×ÔfoldÖ®ºóÔÙmergeÄØ£¿

ÆäʵÊÇÓпÉÄܵģ¬ÎÒÃÇÖ»ÒªÄܹ»È·±£actionµ¼ÖµÄreducerÁ£¶È×㹻С£¬±ÈÈçÖ»ÐÞ¸ÄstateµÄͬһ¸ö²¿·Ö£¬ÊÇ¿ÉÒÔ°´ÕÕÕâÖÖά¶ÈÈ¥×éÖ¯actionµÄ¡£

const a$ = actionsA$.fold(reducerA, initA)
const b$ = actionsB$.fold(reducerB, initB)
const c$ = actionsC$.fold(reducerC, initC)

const state$ = xs.combine(a$, b$, c$)
.map(([a, b, c]) => ({a, b, c}))

Èç¹ûÎÒÃÇÒ»¸ö×é¼þµÄÄÚ²¿×´Ì¬×ã¹»¼òµ¥£¬ÉõÖÁÁ¬actionµÄÀàÐͶ¼¿ÉÒÔ²»ÐèÒª£¬Ö±½Ó´Ó²Ù×÷Ó³É䵽״̬½á¹û¡£

const state$ = xs.fromEvent($('.btn'), click)
.map(e => e.data)

ÕâÑù£¬ÎÒÃÇ¿ÉÒÔÔÚ×é¼þÄÚÔËÐÐÕâÖÖ¼ò»¯°æµÄRedux»úÖÆ£¬¶øÔÚÈ«¾Ö״̬ÉÏÔËÐбȽÏÍêÉÆµÄ¡£ÕâÁ½ÖÖ¶¼ÊÇ»ùÓÚÊý¾Ý¹ÜµÀµÄ£¬È»ºóÔÚÈÝÆ÷×é¼þÖпÉÒÔ°ÑËüÃǺϲ¢£¬´«ÈëÊÓͼ×é¼þ¡£

Õû¸öÁ÷³ÌÈçͼËùʾ£º

  ---------------------
¡ü ¡ý
|-- LocalState
View <-- |
|-- GlobalState
¡ý ¡ü
Action --> Reducer

״̬µÄ·Ö×éÓë¹ÜÀí

»ùÓÚredux-sagaµÄ·â×°¿âdvaÌṩÁËÒ»ÖÖ·ÖÀà»úÖÆ£¬¿ÉÒÔ°ÑÒ»ÀàÒµÎñµÄ¶«Î÷½øÐзÖ×飺

export const project = {
namespace: 'project',
state: {},
reducers: {},
effects: {},
subscriptions: {}
}

´ÓÕâ¸ö½á¹¹¿ÉÒÔ¿´³ö£¬Õâ¸öÔÚdvaÖб»³ÆÎªmodelµÄ¶«Î÷£¬¶¨ÒåÁË£º

ËüÊÇÃæÏòµÄʲôҵÎñÄ£ÐÍ

ÐèÒªÔÚÈ«¾Ö´æ´¢Ê²Ã´ÑùµÄÊý¾Ý½á¹¹

¾­¹ýÄÄЩ²Ù×÷È¥±ä¸üÊý¾Ý

ÃæÏòͬһÖÖÒµÎñʵÌåµÄÊý¾Ý½á¹¹¡¢ÒµÎñÂß¼­¿ÉÒÔ×éÖ¯µ½Ò»Æð£¬ÕâÑù£¬¶ÔÒµÎñ´úÂëµÄά»¤ÊDZȽÏÓÐÀûµÄ¡£¶ÔÒ»¸ö´óÐÍÓ¦ÓÃÀ´Ëµ£¬¿ÉÒÔ¸ù¾ÝÒµÎñÀ´»®·Ömodel¡£Vue¼¼ÊõÕ»µÄVuexÒ²ÊÇÓÃÀàËÆµÄ½á¹¹À´½øÐÐÒµÎñ¹éÀàµÄ£¬ËüÃǶ¼ÊÇÊÜelmµÄÆô·¢¶ø´´½¨£¬Òò´Ë»áÓÐÀàËÆ½á¹¹¡£

»ØÏëµ½ÉÏÒ»½Ú£¬ÎÒÃÇÌáµ½£¬Èç¹ûÈô¸É¸öreducerÐ޸ĵÄÊÇstateµÄ²»Í¬Î»Ö㬿ÉÒÔ·Ö±ðÊÕÁ²Ö®ºó£¬ÔÙ½øÐкϲ¢¡£Èç¹ûÎÒÃǰÑ״̬½á¹¹°´ÕÕÉÏÃæÕâÖÖÒµÎñÄ£Ð͵ķ½Ê½½øÐйÜÀí£¬¾Í¿ÉÒÔ²ÉÓÃÕâÖÖ»úÖÆÀ´·Ö±ðÊÕÁ²¡£ÕâÑù£¬µ¥¸ömodelÄÚ²¿¾ÍÐγÉÁËÒ»¸ö±Õ»·£¬Äܹ»±È½ÏÇåÎúµÄÃèÊö×ÔÉíËù´ú±íµÄÒµÎñº¬Ò壬Ҳ±ãÓÚ×ö²âÊԵȵȡ£

MobXµÄStore¾ÍÊÇÀàËÆÕâÑùµÄÒ»¸ö×éÖ¯ÐÎʽ£º

class TodoStore {
authorStore

@observable todos = []
@observable isLoading = true

constructor(authorStore) {
this.authorStore = authorStore
this.loadTodos()
}

loadTodos() {}
updateTodoFromServer(json) {}
createTodo() {}
removeTodo(todo) {}
}

ÒÀÕÕ֮ǰµÄ˼·£¬ÎÒÃÇËùνµÄmodelÆäʵ¾ÍÊÇÒ»¸öºÏ²¢Ö®ºóÉú³Éstate½á¹¹µÄÊý¾Ý¹ÜµÀ£¬ÒòΪÎÒÃǵĹܵÀÊÇ¿ÉÒÔ×éºÏµÄ£¬ËùÒÔûÓÐÌØ±ðµÄ±ØÒªÈ¥°´ÕÕÉÏÃæÄÇÖֽṹ¶¨Òå¡£

ÄÇô£¬ÔÚÕû¸öÓ¦ÓõÄ×îÉϲ㣬ÊÇ·ñ»¹ÓбØÒªÈ¥×öcombineReducerÕâÖÖ²Ù×÷ÄØ£¿

ÎÒÃÇ֮ǰÌáµ½Ò»¸ö±í´ïʽ£º

View = f(Model)

Õû¸öReact-ReduxÌåϵ£¬¶¼ÊÇÇãÏòÓÚÈÃʹÓÃÕß¾¡¿ÉÄÜÈ¥´ÓÕûÌåµÄ½Ç¶È¹Ø×¢±ä»¯£¬±ÈÈç˵£¬ReduxµÄÊäÈëÊä³ö½á¹ûÊÇÕû¸öÓ¦Óñä¸üǰºóµÄÍêÕû״̬£¬React½ÓÊܵÄÊÇÕû¸ö×é¼þµÄÍêÕû״̬£¬È»ºó£¬ÄÚ²¿ÔÙÈ¥×ödiff¡£

ÎÒÃÇÐèҪעÒâµ½£¬ÎªÊ²Ã´²»ÊÇÖ±½Ó°ÑRedux½ÓÔÚReactÉÏ£¬¶øÊÇͨ¹ýÒ»¸ö½Ð×öreact-reduxµÄ¿âÄØ£¿ÒòΪËüÐèÒª½èÖúÕâ¸ö¿â£¬È¥´ÓÕûÌåµÄstate½á¹¹Éϼì³ö±ä»¯µÄ²¿·Ö£¬Äøø¶ÔÓ¦µÄ×é¼þÈ¥ÖØ»æ¡£

ËùÒÔ£¬ÎÒÃÇ·¢ÏÖÈçÏÂÊÂʵ£º

ÔÚ´¥·¢reducerµÄʱºò£¬ÎÒÃÇÊǾ«È·ÖªµÀÒªÐÞ¸ÄstateµÄʲôλÖõÄ

ºÏ²¢ÍêreducerÖ®ºó£¬Êä³ö½á¹ûÊǸöÍêÕûstate¶ÔÏó£¬ÒѾ­²»ÖªµÀstateµÄʲôλÖñ»Ð޸ĹýÁË

ÊÓͼ×é¼þ±ØÐ뾫ȷµØÄõ½±ä¸üµÄ²¿·Ö£¬²ÅÄÜÅųýÎÞЧµÄäÖȾ

Õû¸ö¹ý³Ì£¬ÊǾ­ÀúÁ˱ä¸üÐÅÏ¢µÄÓµÓСª¡ª¶ªÊ§¡ª¡ªÖØÐÂÓµÓйý³ÌµÄ¡£Èç¹ûÎÒÃǵÄÊý¾ÝÁ÷Êǰ´ÕÕÒµÎñÄ£ÐÍÈ¥·Ö±ð½¨Á¢µÄ£¬ÎÒÃÇ¿ÉÒÔ²»ÐèҪȥ×öÕâ¸öÈ«ºÏ²¢µÄ²Ù×÷£¬¶øÊǸù¾ÝÐèÒª£¬Ñ¡ÔñºÏ²¢ÆäÖÐÒ»²¿·ÖÈ¥½øÐÐÔËËã¡£

ÕâÑùµÄ»°£¬Õû¸ö±ä¸ü¹ý³Ì¶¼ÊǾ«È·µÄ£¬¼õÉÙÁ˲»±ØÒªµÄdiffºÍ»º´æ¡£

Èç¹ûΪÁËʹÓÃredux-toolµÄ»°£¬¿ÉÒÔÈ«²¿ºÏ²¢ÆðÀ´£¬Íùredux-toolÀïÃæÐ´Èëÿ´ÎµÄÈ«¾Ö״̬±ä¸üÐÅÏ¢£¬¹©µ÷ÊÔʹÓ㬶øÒòΪÊý¾Ý¹ÜµÀÊÇÀÁÖ´Ðеģ¬ÎÒÃÇ¿ÉÒÔ×öµ½¿ª·¢½×¶Î¶©ÔÄÕû¸östate£¬¶øÔËÐÐʱ²»¶©ÔÄ£¬ÒÔ¼õÉÙ²»±ØÒªµÄºÏ²¢¿ªÏú¡£

ModelµÄ½á¹¹

ÎÒÃÇ´Óºê¹ÛÉ϶ÔÒµÎñÄ£ÐÍ×÷ÁË·ÖÀàµÄ×éÖ¯£¬½ÓÏÂÀ´¾ÍÐèÒª¹Ø×¢Ã¿ÖÖÒµÎñÄ£Ð͵ÄÊý¾Ý¹ÜµÀÉÏ£¬Êý¾Ý¸ñʽӦµ±ÈçºÎ¹ÜÀíÁË¡£

ÔÚRedux£¬VuexÕâÑùµÄʵ¼ùÖУ¬ºÜ¶àÈ˶¼»áÓÐÕâÑùµÄ¾À½á£º

ÔÚstoreÖУ¬Ó¦µ±ÒÔʲôÑùµÄÐÎʽ´æ·ÅÊý¾Ý£¿

ͨ³££¬»áÓÐÁ½ÖÖÑ¡Ôñ£º

´òƽÁ˵ÄÊý¾Ý£¬¾¡¿ÉÄÜÒÔidÕâÑùµÄkeyÈ¥Ë÷Òý

Ìù½üÊÓͼµÄÊý¾Ý£¬±ÈÈçÊ÷Ðνṹ

ǰÕßÓÐÀûÓÚ²éѯºÍ¸üУ¬¶øºóÕßÄܹ»Ö±½Ó¸øÊÓͼʹÓá£ÎÒÃÇÐèҪ˼¿¼Ò»¸öÎÊÌ⣺

½«´¦Àí¹ýºóµÄÊÓͼ״̬´æ·ÅÔÚstoreÖÐÊÇ·ñºÏÀí£¿

ÎÒÈÏΪ²»Ó¦µ±´æÌ«Æ«ÏòÊÓͼ½á¹¹µÄÊý¾Ý£¬ÀíÓÉÈçÏ£º

ijһÖÖÒµÎñÊý¾Ý£¬ºÜ¿ÉÄܱ»²»Í¬µÄÊÓͼʹÓã¬ËüÃǵĽṹδ±ØÒ»Ö£¬Èç¹û°´ÕÕÊÓͼµÄ¸ñʽ´æ´¢£¬¾ÍÒªÔÚstoreÖдæ·Å²»Í¬ÐÎʽµÄ¶à·Ý£¬ËüÃÇÖ®¼äµÄͬ²½ÊǸö´óÎÊÌ⣬Ҳ»áµ¼ÖÂstoreÑÏÖØÅòÕÍ£¬Ëæ×ÅÓ¦ÓùæÄ£µÄÀ©´ó£¬Õâ¸öÎÊÌâ¸ü¼ÓÑÏÖØ¡£

¼ÈÈ»ÕâÑù£¬ÄǾÍÒª½â¾ö´ÓÕâÖÖÊý¾Ýµ½ÊÓͼËùÐèÊý¾ÝµÄ¹ØÁª¹ØÏµ£¬Õâ¸ö´¦Àí¹ý³Ì·ÅÔÚÄÄÀïºÏÊÊÄØ£¿

ÔÚReduxºÍVuexÖУ¬ÎªÁËÊý¾ÝµÄ±ä¸üÊܿأ¬Ó¦µ±ÔÚreducer»òÕßmutationÖÐÈ¥×ö״̬±ä¸ü£¬µ«ÕâÁ½ÕßÐ޸ĵÄÓÖÊÇstore£¬ÕâÓÖÈÆ»ØÈ¥ÁË£ºÎªÁËÊÓͼäÖȾ·½±ã¶ø¼ÆËã³öÀ´µÄÊý¾Ý£¬Èç¹ûÔÚreducer»òÕßmutationÖÐ×ö£¬»¹Êǵ÷ÅÔÚstoreÀï¡£

ËùÒÔ£¬¾ÍÓÐÁËÒ»¸ö½áÂÛ£º´ÓԭʼÊý¾Ýµ½ÊÓͼÊý¾ÝµÄ´¦Àí¹ý³Ì²»Ó¦µ±·ÅÔÚreducer»òmutationÖУ¬ÄǺÜÏÔÈ»¾ÍÓ¦µ±·ÅÔÚÊÓͼ×é¼þµÄÄÚ²¿È¥×ö¡£

ÎÒÃÇÀíÒ»ÏÂÕâ¸ö¹ØÏµ£º

[ View <-- VM ] <-- State
¡ý ¡ü
Action --> Reducer

Õâ¸öͼÖУ¬·½À¨ºÅµÄ²¿·ÖÊÇÊÓͼ×é¼þ£¬ËüÄÚ²¿°üº¬ÁË´Óԭʼstateµ½viewËùÐèÊý¾ÝµÄ±ä¶¯£¬ÒÔReactΪÀý£¬ÓôúÂë±íʾ£º

render(props) {
const { flatternData } = props
const viewData = formatData(flatternData)
// ...render viewData
}

¾­¹ýÕâÑùµÄ²ð·ÖÖ®ºó£¬storeÖеĽṹ¸ü¼Ó¼òµ¥ÇåÎú£¬reducerµÄÖ°ÔðÒ²¸üÉÙÁË£¬ÊÓͼÓиü´óµÄ×ÔÖ÷Ȩ£¬È¥´ÓԭʼÊý¾Ý×é×°³É×Ô¼ºÒªµÄÑù×Ó¡£

ÔÚ´óÐÍÒµÎñ¿ª·¢µÄ¹ý³ÌÖУ¬storeµÄ½á¹¹Ó¦µ±¾¡ÔçÎȶ¨ÎÞÕùÒ飬±ÜÃâÒòΪÊÓͼµÄ±ä»¯¶ø²»Í£µ÷Õû£¬Òò´Ë£¬´æ·ÅÏà¶ÔԭʼһЩµÄÊý¾ÝÊǸüºÏÀíµÄ£¬ÕâÑùÒ²»á±ÜÃâÊÓͼ×é¼þÔÚÀí½âÊý¾ÝÉÏµÄÆçÒå¡£¶à¸öÊÓͼºÜ¿ÉÄÜÒÔ²»Í¬µÄÒµÎñº¬ÒåÈ¥¿´´ý״̬Ê÷ÉϵÄͬһ¸ö·ÖÖ§£¬Õâ»áÔì³ÉºÜ¶àÂé·³¡£

ÎÒÃÇÆÚÍûÔÚstoreÖд洢¸üÆ«ÏòÓÚ¸ü±âƽ»¯µÄԭʼÊý¾Ý¡£¼´Ê¹ÊǶÔÓÚ´Óºó¶Ë·µ»ØµÄ²ã¼¶Êý¾Ý£¬Ò²¿ÉÒÔ½èÖúnormalizrÕâÑùµÄ¸¨Öú¿âÈ¥Õ¹¿ª¡£

Õ¹¿ªÇ°£º

[{
id: 1,
title: 'Some Article',
author: {
id: 1,
name: 'Dan'
}
}, {
id: 2,
title: 'Other Article',
author: {
id: 1,
name: 'Dan'
}
}]

Õ¹¿ªºó£º

{
result: [1, 2],
entities: {
articles: {
1: {
id: 1,
title: 'Some Article',
author: 1
},
2: {
id: 2,
title: 'Other Article',
author: 1
}
},
users: {
1: {
id: 1,
name: 'Dan'
}
}
}
}

ºÜÃ÷ÏÔ£¬ÕâÑùµÄ½á¹¹¶ÔÎÒÃǵĺóÐø²Ù×÷ÊDZȽϱãÀûµÄ¡£ÒòΪÎÒÃÇÊÖÀïÓÐÊý¾Ý¹ÜµÀÕâÑùµÄÀûÆ÷£¬ËùÒÔ²»µ£ÐÄÊý¾ÝÊDZȽÏԭʼµÄ¡¢ÀëÉ¢µÄ£¬ÒòΪ¶ÔËüÃÇ×÷¾ÛºÏ´¦ÀíÊDZȽÏÈÝÒ׵ģ¬ËùÒÔ¿ÉÒÔ·ÅÐĵذÑÕâЩÊý¾Ý´ò³É±È½ÏԭʼµÄÐÎ̬¡£

ǰ¶ËµÄÊý¾Ý½¨Ä£

֮ǰÎÒÃÇÌáµ½¹ýstoreÀïÃæ´æ·ÅµÄÊÇ±âÆ½»¯µÄԭʼÊý¾Ý£¬µ«ÊÇÐèҪעÒâµ½£¬Í¬ÑùÊÇ±âÆ½»¯£¬¿ÉÄÜÓÐÏñmapÄÇÑù»ùÓÚid×÷Ë÷ÒýµÄ£¬Ò²¿ÉÄÜÓлùÓÚÊý×éÐÎʽ´æ·ÅµÄ£¬ºÜ¶àʱºò£¬ÎÒÃÇÊÇÁ½ÖÖ¶¼ÒªµÄ¡£

ÔÚ¸ü¸´ÔÓµÄÇé¿öÏ£¬»¹»áÐèÒªÓжÔÏó¹ØÏµµÄ¹ØÁª£¬Ò»¶ÔÒ»£¬Ò»¶Ô¶à£¬¶à¶Ô¶à£¬Õâ¾Íµ¼ÖÂÊÓͼÔÚÐèҪʹÓÃstoreÖеÄÊý¾Ý½øÐÐ×éºÏµÄʱºò£¬²»¹ÜÊÇstoreµÄ½á¹¹¶¨Ò廹ÊÇ×éºÏ²Ù×÷¶¼±È½ÏÂé·³¡£

Èç¹ûǰ¶ËÊǵ¥Ò»ÒµÎñÄ£ÐÍ£¬ÄÇÎÒÃǰ´ÕÕǰһ½ÚµÄ·½°¸£¬ÒѾ­¿ÉÒÔ×öµ½µ±Êý¾Ý±ä¸üµÄʱºò£¬°Ñµ±Ç°×´Ì¬ÍÆË͸ø¶©ÔÄËüµÄ×é¼þ£¬µ«Êµ¼ÊÇé¿öÏ£¬¶¼»á±ÈÕâ¸ö¸´ÔÓ£¬ÒµÎñÄ£ÐÍÖ®¼ä»á´æÔÚ¹ØÁª¹ØÏµ£¬ÔÚÒ»¸öÄ£Ðͱä¸üµÄʱºò£¬¿ÉÄÜÐèÒª×Ô¶¯´¥·¢Ëù¹ØÁªµ½µÄÄ£Ð͵ĸüС£

Èç¹û¸´ÔӶȽϵͣ¬ÎÒÃÇ¿ÉÒÔÊÖ¶¯´¦ÀíÕâÖÖ¹ØÁª£¬Èç¹ûÁª¶¯¹ØÏµ·Ç³£¸´ÔÓ£¬¿ÉÒÔ¿¼ÂǶÔÊý¾Ý°´ÕÕʵÌå¡¢¹ØÏµ½øÐн¨Ä££¬ÉõÖÁ¼ÓÈëÒ»¸öÃÔÄã°æµÄÀàËÆORMµÄ¿âÀ´¶¨ÒåÕâÖÖ¹ØÏµ¡£

¾ÙÀýÀ´Ëµ£º

×éÖ¯¿ÉÒÔÓÐϲã×éÖ¯

×é֯ϿÉÒÔÓÐÈËÔ±

×éÖ¯ºÍÈËÔ±ÊÇÒ»¶Ô¶àµÄ¹ØÏµ

Èç¹ûÒ»¸öÊý¾ÝÁ÷¶©ÔÄÁËij¸ö×éÖ¯µÄ»ù±¾ÐÅÏ¢£¬Ëü¿ÉÄÜÖ»·´Ó³Õâ¸ö×éÖ¯×ÔÉíʵÌåÉϵıä¸ü£¬¶øÁíÍâÒ»¸öÊý¾ÝÁ÷¶©ÔÄÁ˸Ã×éÖ¯µÄÈ«²¿ÐÅÏ¢£¬ÓÃÓÚÐγÉÒ»¸öʵʱ¸üеÄ×é֯ȫÊÓͼ£¬ÔòÐèÒª¾ÛºÏ¸Ã×éÖ¯ºÍ¿ÉÄܵÄϼ¶×éÖ¯¡¢ÈËÔ±µÄ±ä¶¯»ã×Ü¡£

ÉϲãÊÓͼ¿ÉÒÔ¸ù¾Ý×Ô¼ºµÄÐèÒª£¬Ñ¡Ôñ´Ó²»Í¬µÄÊý¾ÝÁ÷¶©ÔIJ»Í¬¸´ÔӶȵÄÐÅÏ¢¡£ÔÚÕâÖÖÇé¿öÏ£¬¿ÉÒÔ°ÑÕû¸öORMÄ£¿éÕûÌåÊÓΪһ¸öÍⲿµÄÊý¾ÝÔ´¡£

Õû¸öÁ÷³ÌÈçÏ£º

[ View <-- VM ] <-- [State <-- ORM]
¡ý ¡ü
Action --> Reducer

ÕâÀïÃæÓм¸¸öÐèҪעÒâµÄµØ·½£º

Ò»¸öactionʵ¼ÊÉÏ»¹ÊǶÔÓ¦µ½Ò»¸öreducer£¬È»ºó·¢Æð¶ÔstateµÄ¸ü¸Ä£¬µ«ÒòΪstateÒѾ­²»ÊǼòµ¥½á¹¹ÁË£¬ËùÒÔÎÒÃDz»ÄÜÖ±½Ó¸Ä£¬¶øÊÇͨ¹ýÕâ²ãÀàËÆORMµÄ¹ØÏµÈ¥¸Ä¡£

¶ÔORMµÄÒ»´ÎÐ޸ģ¬¿ÉÄÜ»á²úÉú¶ÔstateµÄÈô¸É´¦¸Ä¶¯£¬±ÈÈç˵£¬¸ÄÁËÒ»¸öÊý¾Ý£¬¿ÉÄÜ»áÍÆµ¼³öÒµÎñÉÏÓëÖ®ÓйØÏµµÄÒ»¿é¹ØÁªÊý¾ÝµÄ±ä¸ü¡£

Èç¹ûÊÇ»ùÓÚreact-reduxÕâÑù»ùÓÚdiffµÄ»úÖÆ£¬Í¬Ê±ÐÞ¸ÄstateµÄ¶à¸öλÖÃÊÇ¿ÉÒԵ쬵«ÔÚÎÒÃÇÕâÌ×»úÖÆÀÒòΪûÓÐÁËÏȺϲ¢ÐÞ¸ÄÔÙdiffµÄ¹ý³Ì£¬ËùÒԺܿÉÄܶà¸öλÖõÄÐÞ¸ÄÐèҪͨ¹ýORMµÄ¹ØÁª£¬ÑÓÉì³ö²»Í¬µÄ¹ÜµÀÀ´¡£

ÊÓͼ¶©ÔĵÄstate±ä¸ü£¬Ö»ÄÜ×éºÏÔËË㣬²»Ó¦µ±ÔٸɱðµÄÊÂÇéÁË¡£

ÔÚÕâôһÖÖÌåϵÏ£¬Êµ¼ÊÉÏǰ¶Ë´æÔÚ×ÅÒ»¸öÀàËÆÊý¾Ý¿âµÄ»úÖÆ£¬ÎÒÃÇ¿ÉÒÔ°ÑÿÖÖÊý¾ÝµÄ±ä¶¯Ô­×Ó»¯£¬Ò»´ÎÌá½»Ö»¸üе¥Ò»ÀàÐ͵ÄʵÌå¡£ÕâÑù£¬ÎÒÃÇÏ൱ÓÚÔÚǰ¶Ë²¿·Ö×öÁËÒ»¸ö¶Áд·ÖÀ룬¶ÁÈ¡µÄ²¿·ÖÊDZ»ÊµÊ±¸üÐµģ¬¿ÉÒÔ°üº¬Ò»ÖÖÀàËÆÓαêµÄ»úÖÆ£¬¹©ÊÓͼ×é¼þ¶©ÔÄ¡£

ÏÂÃæÊÇRedux-ORMµÄ¼òµ¥Ê¾Àý£¬ÊDz»ÊǺÜÏñÔÚ²Ù×÷Êý¾Ý¿â£¿

class Todo extends Model {}
Todo.modelName = 'Todo';
Todo.fields = {
user: fk('User', 'todos'),
tags: many('Tag', 'todos'),
};

class Tag extends Model {}
Tag.modelName = 'Tag';
Tag.backend = {
idAttribute: 'name';
};

class User extends Model {}
User.modelName = 'User';

С½á

ÎÄÕÂ×ʼ£¬ÎÒÃÇÌáµ½×îÀíÏëµÄ×é¼þ»¯¿ª·¢·½Ê½ÊÇÒÀÍÐ×é¼þÊ÷µÄ½á¹¹£¬Ã¿¸ö×é¼þÍê³É×Ô¼ºÄÚ²¿ÊÂÎñµÄ´¦Àí¡£µ±×é¼þÖ®¼ä³öÏÖͨÐÅÐèÇóµÄʱºò£¬²»µÃ²»½èÖúÓÚReduxÖ®ÀàµÄ¿âÀ´×öת·¢¡£

µ«ÊÇReduxµÄÀíÄÓÖ²»½ö½öÊÇÖ»¶¨Î»ÓÚ×öת·¢£¬Ëü¸üÊÇÆÚÍûÄܹÜÀíÕû¸öÓ¦ÓõÄ״̬£¬Õâ·´¹ýÀ´¶Ô×é¼þµÄʵÏÖ£¬ÉõÖÁÓ¦ÓõÄÕûÌå¼Ü¹¹Ôì³ÉÁ˽ϴóµÄÓ°Ïì¡£

ÎÒÃÇÈÔÈ»»áÆÚÍûÓÐÒ»ÖÖ»úÖÆ£¬Äܹ»Ïñ·ÖÐÎÄÇÑù½øÐпª·¢£¬µ«ÓÖÏ£ÍûÄܹ»±ÜÃâ״̬¹ÜÀíµÄ»ìÂÒ£¬Òò´Ë£¬MVIÕâÑùµÄģʽijÖ̶ֳÈÉÏÄܹ»Âú×ãÕâÖÖÐèÇ󣬲¢ÇÒ´ïµ½Âß¼­ÉϵÄ×ÔÇ¢¡£

Èç¹ûÒÔMVIµÄÀíÄîÀ´½øÐпª·¢£¬ËüµÄÒ»¸ö×é¼þÆäʵÊÇ£ºÊý¾ÝÄ£ÐÍ¡¢¶¯×÷¡¢ÊÓͼÈýÕߵļ¯ºÏ£¬Õâôһ¸öMVI×é¼þÏ൱ÓÚReact-ReduxÌåϵÖУ¬connectÁËstoreÖ®ºóµÄ¸ß½××é¼þ¡£

Òò´Ë£¬ÎÒÃÇÖ»Ðè°Ñ´«Í³µÄ×é¼þ×÷һЩ´¦Àí£º

ÊÓͼ¸ôÀ룬´¿»¯ÎªÕ¹Ê¾×é¼þ

ÄÚ²¿×´Ì¬µÄ¶¨ÒåÇåÎú»¯

ÃèÊö³öÄÚ²¿×´Ì¬µÄÀ´Ô´¹ØÏµ£ºstate := actions.reduce(reducer, initState)

½«ÄÚ²¿µÄ¶¯×÷ÒÔactionµÄ·½Ê½Êä³öµ½ÉÏÃæÄǸö±í´ïʽ¹ØÏµÖÐ

ÕâÑù£¬×é¼þ¾ÍÊÇ×ÔÇ¢µÄÒ»¸ö¶«Î÷£¬Ëü²»¹Ø×¢ÍâÃæÊDz»ÊÇRedux£¬ÓÐûÓÐÈ«¾ÖµÄstore£¬Ã¿¸ö×é¼þ×Ô¼ºÄÚ²¿ÔËÐÐ×ÅÒ»¸öÀàËÆReduxµÄ¶«Î÷£¬ÕâÑùµÄÒ»¸ö×é¼þ¿ÉÒÔ¸ü¼ÓÈÝÒ×ÓëÆäËû×é¼þ½øÐÐÅäºÏ¡£

ÓëReduxÏà±È£¬ÕâÌ×»úÖÆµÄÌØµãÊÇ£º

²»ÐèÒªÏÔʽ¶¨ÒåÕû¸öÓ¦ÓõÄstate½á¹¹

È«¾Ö״̬ºÍ±¾µØ×´Ì¬¿ÉÒÔÁ¼ºÃµØÍ³Ò»ÆðÀ´

¿ÉÒÔ´æÔÚ·ÇÏÔʽµÄaction£¬²¢ÇÒaction¿ÉÒÔ²»¼¯ÖнâÎö£¬¶øÊÇ·ÖÉ¢Ö´ÐÐ

¿ÉÒÔ´æÔÚ·ÇÏÔʽµÄreducer£¬Ëü¸½×ÅÔÚÊý¾Ý¹ÜµÀµÄÔËËãÖÐ

Òì²½²Ù×÷ÏÈÓ³ÉäΪÊý¾Ý£¬È»ºóͨ¹ýµ¥ÏòÁª¶¯¹ØÏµ×éºÏ¼ÆËã³öÊÓͼ״̬

»Ø¹ËÕû¸ö²Ù×÷¹ý³Ì£º

Êý¾ÝµÄдÈ벿·Ö£¬¶¼ÊÇͨ¹ýÀàËÆReduxµÄactionÈ¥×ö

Êý¾ÝµÄ¶ÁÈ¡²¿·Ö£¬¶¼ÊÇͨ¹ýÊý¾Ý¹ÜµÀµÄ×éºÏ¶©ÔÄÈ¥×ö

½èÖúRxJS»òÕßxstreamÕâÑùµÄÊý¾Ý¹ÜµÀµÄÀíÄÎÒÃÇ¿ÉÒÔÖ±¹ÛµØ±í´ï³öÊý¾ÝµÄÕû¸ö±ä¸ü¹ý³Ì£¬Ò²¿ÉÒ԰Ѷà¸öÊý¾ÝÁ÷½øÐбã½ÝµÄ×éºÏ¡£Èç¹ûʹÓÃRedux£¬Õý³£Çé¿öÏ£¬ÐèÒªÒýÈëÖÁÉÙÒ»ÖÖÒì²½Öмä¼þ£¬¶øRxJSÒòΪ×ÔÉí¾ÍÊÇΪ´¦ÀíÒì²½²Ù×÷¶øÉè¼ÆµÄ£¬ËùÒÔ£¬Ö»ÐèÓÃËü¿ØÖƺôÓÒì²½²Ù×÷µ½Í¬²½µÄÊÕÁ²£¬¾Í¿ÉÒÔ´ïµ½ReduxÒ»ÑùµÄÊý¾Ýµ¥ÏòÁ÷¶¯¡£Èç¹ûÏëÒªÔÚÊý¾Ý¹ÜµÀÖнÓÈëÒ»¶Î³Ðµ£Öмä¼þÖ°ÔðµÄ¶«Î÷£¬Ò²ÊǷdz£ÈÝÒ׵ġ£

¶øRxJS¡¢xstreamËùÌṩµÄÊý¾ÝÁ÷×éºÏ¹¦Äܷdz£Ç¿´ó£¬ÌìÈ»ÌṩÁËÒ»ÇÐÒì²½²Ù×÷µÄͳһ³éÏó£¬ÕâÒ»µãÊÇÆäËûÒì²½·½°¸ºÜÄÑÏà±ÈµÄ¡£

ËùÒÔ£¬ÕâЩ¿â£¬ÒòΪӵÓÐÏÂÃæÕâÐ©ÌØÐÔ£¬ºÜÊʺÏ×öÊý¾ÝÁ÷¿ØÖÆ£º

¶ÔʼþµÄ¸ß¶È³éÏó

ͬ²½ºÍÒì²½µÄͳһ»¯´¦Àí

Êý¾Ý±ä¸üµÄ³ÖÐø¶©ÔÄ£¨¶©ÔÄģʽ£©

Êý¾ÝµÄÁ¬Ðø±ä¸ü£¨¹ÜµÀÆ´½Ó£©

Êý¾Ý±ä¸üµÄµÄ×éºÏÔËË㣨¹ÜµÀ×éºÏ£©

ÀÁÖ´ÐУ¨ÎÞ¶©ÔÄÕߣ¬Ôò²»Ö´ÐУ©

»º´æµÄÖмä½á¹û

¿ÉÖØ·ÅµÄÀúÊ·¼Ç¼

¡­¡­µÈµÈ

   
2035 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

¹È¸è½ÌÄãÈçºÎ¹¹½¨Ò»¸öÓÅÐãµÄÒÆ¶¯ÍøÕ¾
ÈçºÎ¸ßЧµØ¹ÜÀíÍøÕ¾¾²Ì¬×ÊÔ´
¸ßÐÔÄÜÍøÕ¾½¨ÉèµÄ×î¼Ñʵ¼ù
Ïл°ÍøÕ¾×ó²àµ¼º½µÄʵÏÖ
 
Ïà¹ØÎĵµ

ÍøÕ¾½¨Éè·½°¸Á÷³Ì
ÍøÕ¾½¨Éècss½Ì³Ì
ÆóÒµÍøÕ¾½¨ÉèÓëÍÆ¹ã
ÍøÕ¾½¨Éè·½°¸Êé
Ïà¹Ø¿Î³Ì

Éè¼ÆÄ£Ê½Ô­ÀíÓëÓ¦ÓÃ
´ÓÐèÇó¹ý¶Éµ½Éè¼Æ
Èí¼þÉè¼ÆÔ­ÀíÓëʵ¼ù
ÈçºÎ±àд¸ßÖÊÁ¿´úÂë
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

Ê®Ììѧ»áDIV+CSS(WEB±ê×¼)
HTML 5µÄ¸ïУº½á¹¹Ö®ÃÀ
½éÉÜ27¿î¾­µäµÄCSS¿ò¼Ü
35¸öÓд´ÒâµÄ404´íÎóÒ³Ãæ
×îÈÝÒ×·¸µÄ13¸öJavaScript´íÎó
Éè¼ÆÒ×Àí½âºÍ²Ù×÷µÄÍøÕ¾

Éè¼ÆÄ£Ê½Ô­ÀíÓëÓ¦ÓÃ
´ÓÐèÇó¹ý¶Éµ½Éè¼Æ
Èí¼þÉè¼ÆÔ­ÀíÓëʵ¼ù
ÈçºÎ±àд¸ßÖÊÁ¿´úÂë
µ¥Ôª²âÊÔ¡¢Öع¹¼°³ÖÐø¼¯³É
Èí¼þ¿ª·¢¹ý³ÌÖ¸ÄÏ

¶«Èí¼¯ÍÅ ´úÂëÖØ¹¹
ij½ðÈÚÈí¼þ·þÎñÉÌ ¼¼ÊõÎĵµ
Öдïµçͨ Éè¼ÆÄ£Ê½Ô­ÀíÓëʵ¼ù
·¨¹úµçÐÅ ¼¼ÊõÎĵµ±àдÓë¹ÜÀí
Î÷ÃÅ×Ó Ç¶ÈëʽÉè¼ÆÄ£Ê½
ÖÐд󶫷½ÈËÊÙ ¼¼ÊõÎĵµ±àд