2018幎ãæ¥ãŠãã¢ããªã±ãŒã·ã§ã³ãäœæããå€ãã®çŽ æŽãããæ¹æ³ãèŠã€ãããŸããããããã³ããšã³ãéçºè
ã®ç¡æ°ã®è»éã¯ãWebãããžã§ã¯ãã®ã·ã³ãã«ããšæè»æ§ã®ããã«ãŸã æŠãç¶ããŠããŸãã 圌ãã¯ããšã©ãŒã®ãªããœãããŠã§ã¢ã¢ãŒããã¯ãã£ãèŠã€ããŠãè¿
éãã€å¹ççã«äœæ¥ãè¡ããããã«ãããšããã倧åãªç®æšãéæããããã«ãæ¯æè²»ãããŠããŸãã ç§ã¯ãããã®éçºè
ã®äžäººã§ãã åã€ãã£ã³ã¹ãäžããŠãããé¢çœããã®ãèŠã€ããããšãã§ããã
Reactã
Reduxãªã©ã®ããŒã«ã«ãããWebéçºã¯æ£ããæ¹åã«å€§ããªäžæ©ãèžã¿åºãããš
ãã§ããŸããã ãã ãããããã ãã§ã¯å€§èŠæš¡ãªã¢ããªã±ãŒã·ã§ã³ãäœæããã«ã¯äžååã§ãã Webã¢ããªã±ãŒã·ã§ã³ã®ã¯ã©ã€ã¢ã³ãåŽéšåã®éçºç¶æ³ã¯ãã¹ããŒããã·ã³ã®äœ¿çšã倧å¹
ã«æ¹åã§ããããã§ãã ãããã«ã€ããŠã¯ããã®è³æã§èª¬æããŸãã ãšããã§ããããããããã®ãã·ã³ã®ããã€ããæ¢ã«æ§ç¯ããŠããããããã«ã€ããŠã¯ãŸã ç¥ããªãã
ã¹ããŒããã·ã³ã®çŽ¹ä»
ã¹ããŒããã·ã³ã¯ãèšç®ã®æ°åŠã¢ãã«ã§ãã ããã¯æœè±¡çãªæŠå¿µã§ããããã·ã³ã¯ããŸããŸãªç¶æ
ãæã€ããšãã§ããŸãããããæç¹ã§ã¯ãã®ãã¡ã®1ã€ã ãã«ãšã©ãŸããŸãã æãæåãªã¹ããŒã
ãã·ã³ã¯ãã¥ãŒãªã³ã°ãã·ã³ã ãšæããŸãã ããã¯ãç¡å¶éã®æ°ã®ç¶æ
ãæã€ãã·ã³ã§ããã€ãŸããç¡å¶éã®æ°ã®ç¶æ
ãæã€ããšãã§ããŸãã ã»ãšãã©ã®å Žåãç¶æ
ã®æ°ãæéã§ããããããã¥ãŒãªã³ã°ãã·ã³ã¯ææ°ã®ã€ã³ã¿ãŒãã§ã€ã¹éçºã®ããŒãºãååã«æºãããŠããŸããã ãã®ãããç¶æ
ã®æ°ãéãããŠãããã·ã³ããŸãã¯ãã°ãã°åŒã°ããããã«ãæéç¶æ
ãã·ã³ã¯ãç§ãã¡ã«ãšã£ãŠããè¯ãã§ãã ããã¯
Mily ãã·ã³ãš
Mooreãã·ã³ã§ãã
2ã€ã®éãã¯ãã ãŒã¢ãªãŒãããã³ã以åã®ç¶æ
ã®ã¿ã«åºã¥ããŠç¶æ
ãå€æŽããããšã§ãã ãã ãããããã¯ãŒã¯äžã§è¡ããããŠãŒã¶ãŒã®ã¢ã¯ã·ã§ã³ãããã»ã¹ãªã©ãå€ãã®å€éšèŠå ããããŸããã€ãŸããã ãŒã¢ãã·ã³ãç§ãã¡ã«ã¯é©ããŠããªããšããããšã§ãã ç§ãã¡ãæ¢ããŠããã®ã¯ãMilesãã·ã³ã«éåžžã«ãã䌌ãŠããŸãã ãã®æéç¶æ
ãã·ã³ã«ã¯åæç¶æ
ãããããã®åŸãå
¥åããŒã¿ãšãã®çŸåšã®ç¶æ
ã«åºã¥ããŠãæ°ããç¶æ
ã«ãªããŸãã
ã¹ããŒããã·ã³ã®åäœã説æããæãç°¡åãªæ¹æ³ã®1ã€ã¯ãå転åŒæ¹ææ©ãšã®é¡æšãéããŠãããèæ
®ããããšã§ãã éãããç¶æ
ã®ã»ããããããŸãïŒããã¯éããŠãããéããŠããããšãã§ããŸãã ç§ãã¡ã®å転åŒæ¹æå£ã¯ãç¹å®ã®ãšãªã¢ãžã®å
¥ãå£ããããã¯ããŸãã 圌ã«3ã€ã®ã¹ã©ãããåãããã©ã ãšããéãåãåãã¡ã«ããºã ãæãããŠãã ããã ã³ã€ã³ãã³ã€ã³ã¢ã¯ã»ãã¿ãŒã«éãããšéããã¿ãŒã³ã¹ã¿ã€ã«ãééã§ããŸããã³ã€ã³ã¢ã¯ã»ãã¿ãŒã¯ããã€ã¹ãéããç¶æ
ã«ããã¿ãŒã³ã¹ã¿ã€ã«ãééããããã«ããŒãæŒããŸãã æ¹æå£ãééããåŸãåã³éããŸãã 以äžã«ããããã®ç¶æ
ãããã³å¯èœãªå
¥åä¿¡å·ãšç¶æ
éã®é·ç§»ã瀺ãç°¡åãªå³ã瀺ããŸãã

å転åŒæ¹æå£ã®åæç¶æ
ã¯ãã¯ããŒãºãïŒããã¯ïŒã§ãã äœå圌ã®ããŒãæŒããŠãã圌ã¯éãããŸãŸã«ãªããŸãã ãã ããã³ã€ã³ããããããããšãã¿ãŒã³ã¹ã¿ã€ã«ã¯ããªãŒãã³ãïŒããã¯è§£é€ïŒç¶æ
ã«ãªããŸãã çŸæç¹ã§ã¯ãå転åŒæ¹æå£ã¯éãããŸãŸãªã®ã§ãå¥ã®ã³ã€ã³ã¯äœãå€æŽããŸããã äžæ¹ãã¿ãŒã³ã¹ã¿ã€ã«ããŒãæŒãããšã¯çã«ããªã£ãŠããããããéãæããããšãã§ããŸãã ããã«ããã®ã¢ã¯ã·ã§ã³ã¯ãæéç¶æ
ãã·ã³ãåæã®ãéãããç¶æ
ã«ç§»è¡ããŸãã
å転åŒæ¹æå£ãå¶åŸ¡ããå¯äžã®é¢æ°ãå®è£
ããå¿
èŠãããå Žåã¯ããããã2ã€ã®åŒæ°ã«çŠç¹ãåœãŠãå¿
èŠããããŸããããã¯çŸåšã®ç¶æ
ãšã¢ã¯ã·ã§ã³ã§ãã Reduxã䜿çšããŠããå Žåã¯ãããã«æ
£ããŠãããããããŸããã ããã¯ãçŸåšã®ç¶æ
ãååŸããã¢ã¯ã·ã§ã³ãã€ããŒãã«åºã¥ããŠæ¬¡ã®ç¶æ
ã決å®ããæ¢ç¥ã®
ã¬ãã¥ãŒãµãŒé¢æ°ã«äŒŒãŠããŸãã ã¬ãã¥ãŒãµãŒã¯ãã¹ããŒããã·ã³ã®ã³ã³ããã¹ãã«ãããé·ç§»ã§ãã å®éãäœããã®æ¹æ³ã§å€æŽã§ããç¶æ
ãæã€ã¢ããªã±ãŒã·ã§ã³ã¯ãã¹ããŒããã·ã³ãšåŒã°ããŸãã å®éãããããã¹ãŠãäœåºŠãäœåºŠãæåã§å®è£
ãããŠããŸãã
ã¹ããŒããã·ã³ã®é·æã¯äœã§ããïŒ
è·å Žã§ã¯Reduxã䜿çšããŠããŸãããããã¯ç§ãã¡ã«ãŽã£ããã§ãã ããããæ°ã«å
¥ããªãç¹ã«æ°ã¥ãå§ããŸããã äœãã奜ãã§ã¯ãªããããšãã£ãŠããããæ©èœããªããšããæå³ã§ã¯ãããŸããã ããã¯ãã¹ãŠããããžã§ã¯ãã«è€éããè¿œå ããããå€ãã®ã³ãŒããæžãããšãäœåãªãããããšããäºå®ã«é¢ãããã®ã§ãã ãµãŒãããŒãã£ã®ãããžã§ã¯ããéå§ããããã§å®éšã®äœå°ããã£ãã®ã§ãReactãšReduxã§ã®éçºã¢ãããŒããåèããããšã«ããŸããã æ°ã«ãªã£ãŠããããšã«ã€ããŠã¡ã¢ãåãå§ããã¹ããŒããã·ã³ã®æœè±¡åããããã®åé¡ã®ããã€ãã解決ããå¯èœæ§ãé«ãããšã«æ°ä»ããŸããã ããžãã¹ã«åãæãããJavaScriptã§ã¹ããŒããã·ã³ãå®è£
ããæ¹æ³ãèŠãŠã¿ãŸãããã
ç°¡åãªåé¡ã解決ããŸãã ãµãŒããŒAPIããããŒã¿ãååŸãããŠãŒã¶ãŒã«è¡šç€ºããå¿
èŠããããŸãã æåã®ã¹ãããã¯ãåé¡ã«ã€ããŠèãããšããé·ç§»ã§ã¯ãªãç¶æ
ã®èŠ³ç¹ããèããæ¹æ³ãç解ããããšã§ãã ã¹ããŒããã·ã³ã«ç§»ãåã«ãäœæããããã®ãã©ã®ããã«èŠãããã«ã€ããŠãé«ã¬ãã«ã§èª¬æããŸãã
- [
ã®
]ãã¿ã³ãããŒãžã«è¡šç€ºãããŸãã
- ãŠãŒã¶ãŒã¯ãã®ãã¿ã³ãã¯ãªãã¯ããŸãã
- ã·ã¹ãã ã¯ãµãŒããŒã«èŠæ±ãåºããŸãã
- ããŒã¿ãããŠã³ããŒãããŠè§£æããŠããŸãã
- ããŒãžã«ããŒã¿ã衚瀺ãããŸãã
- ãšã©ãŒãçºçãããšã察å¿ããã¡ãã»ãŒãžã衚瀺ãããããŒãžã«
ã®
ãã¿ã³ãåã³è¡šç€ºãããŸããããã«ããããŠãŒã¶ãŒã¯ãµãŒããŒããããŒã¿ãåä¿¡ããããã»ã¹ãåã³éå§ã§ããŸãã
ããã§ãåé¡ãåæããçŽç·çã«èããå®éãæçµçµæãžã®ãã¹ãŠã®å¯èœãªçµè·¯ãã«ããŒããããšããŸãã ããã¹ãããã¯å¥ã®ã¹ãããã«ã€ãªããã次ã®ã¹ãããã¯å¥ã®ã¹ãããã«ã€ãªãããŸãã ã³ãŒãã§ã¯ãããã¯åå²æŒç®åãšããŠè¡šçŸã§ããŸãã ãŠãŒã¶ãŒãšã·ã¹ãã ã®ã¢ã¯ã·ã§ã³ã«åºã¥ããŠæ§ç¯ãããããã°ã©ã ã§æèå®éšãè¡ã£ãŠã¿ãŸãããã
ãŠãŒã¶ãŒããã¿ã³ã2åã¯ãªãã¯ããç¶æ³ã¯ã©ãã§ããïŒ ãµãŒããŒããã®å¿çãåŸ
ã£ãŠããéã«ãŠãŒã¶ãŒããã¿ã³ãã¯ãªãã¯ãããšã©ããªããŸããïŒ èŠæ±ã¯æåããããããŒã¿ãç Žæããå Žåãã·ã¹ãã ã¯ã©ã®ããã«åäœããŸããïŒ
ãã®ãããªç¶æ³ãåŠçããã«ã¯ãäœãèµ·ãã£ãŠããã®ãã瀺ãããŸããŸãªãã©ã°ãå¿
èŠã«ãªãã§ãããã ãã©ã°ã®ååšã¯ã
if
ã®æ°ã®å¢å ãæå³ããããè€éãªã¢ããªã±ãŒã·ã§ã³ã§ã¯ã競åã®æ°ã®å¢å ãæå³ããŸãã
ããã¯ã移è¡æã«èããããã§ãã ããã°ã©ã ã®å€æŽãæ£ç¢ºã«ã©ã®ããã«çºçããããããã³ããããçºçããé åºã«çŠç¹ãåœãŠãŸãã 代ããã«ãã¢ããªã±ãŒã·ã§ã³ã®ããŸããŸãªç¶æ
ã«çŠç¹ãåããããšããã¹ãŠã倧å¹
ã«ç°¡çŽ åãããŸãã ããã€ã®æ¡ä»¶ããããŸããïŒ åœŒãã®ã€ã³ãããã¯äœã§ããïŒ åãäŸã䜿çšããŸãã
idle
ç¶æ
ïŒåçŽïŒã ãã®ç¶æ
ã§ã¯ã
ã®
ãã¿ã³ã衚瀺ãããŠãŒã¶ãŒã®ã¢ã¯ã·ã§ã³ãåŸ
ã¡ãŸãã å¯èœãªã¢ã¯ã·ã§ã³ã¯æ¬¡ã®ãšããã§ãã
fetching
ã®ç¶æ
ã èŠæ±ã¯ãµãŒããŒã«éä¿¡ãããŠãããå®äºãåŸ
ã£ãŠããŸãã å¯èœãªã¢ã¯ã·ã§ã³ã¯æ¬¡ã®ãšããã§ãã
- ã¹ããŒã¿ã¹ã¯
error
ã§ãã ãšã©ãŒã¡ãã»ãŒãžã衚瀺ãã[
ã®
]ãã¿ã³ã衚瀺ããŸãã ãã®ç¶æ
ã¯1ã€ã®ã¢ã¯ã·ã§ã³ãåããŸãïŒ
ããã§ã¯ãåãããã»ã¹ã«ã€ããŠèª¬æããŸããããçŸåšã¯ç¶æ
ãšå
¥åããŒã¿ã䜿çšããŠããŸãã
ããã«ãããããžãã¯ãç°¡çŽ åãããäºæž¬ãããããªããŸããã ããã«ãäžèšã®åé¡ã®ããã€ãã解決ããŸããã ãã·ã³ã
fetching
ç¶æ
ã«ãããšãããã¿ã³ã®ããŠã¹ã¯ãªãã¯ã«é¢é£ããã€ãã³ããåãå
¥ããªãããšã«æ³šæããŠãã ããã ãããã£ãŠããŠãŒã¶ãŒããã¿ã³ãã¯ãªãã¯ããŠãããã·ã³ã¯
fetching
ç¶æ
ã«ãããšãã«ãã®ã¢ã¯ã·ã§ã³ã«åå¿ããããã«æ§æãããŠããªããããäœãèµ·ãããŸããã ãã®ã¢ãããŒãã«ãããã³ãŒãããžãã¯ã®äºæããªãåå²ãèªåçã«æé€ãããŸãã
ããã¯ããã¹ãäžã«ããå°ãªãã³ãŒããã«ããŒããå¿
èŠãããããšãæå³ããŸãã ããã«ãçµ±åãã¹ããªã©ã®äžéšã®ã¿ã€ãã®ãã¹ãã¯èªååã§ããŸãã ãã®ã¢ãããŒãã䜿çšãããšãã¢ããªã±ãŒã·ã§ã³ã®å®è¡å
容ãéåžžã«æ確ã«ç解ã§ããå®çŸ©æžã¿ã®ç¶æ
ãšé·ç§»ãééããŠã¹ããŒãã¡ã³ããçæããã¹ã¯ãªãããäœæã§ãããšèããŠãã ããã ãããã®ã¹ããŒãã¡ã³ãã¯ãå¯èœæ§ã®ããåç¶æ
ã«å°éããããšããŸãã¯ç¹å®ã®é·ç§»ã·ãŒã±ã³ã¹ãå®äºããããšã蚌æã§ããŸãã
å®éãã©ã®ç¶æ
ãå¿
èŠããã©ã®ç¶æ
ãæã£ãŠããããç¥ã£ãŠããã®ã§ãå¯èœãªãã¹ãŠã®ç¶æ
ãæžãåºãæ¹ããå¯èœãªãã¹ãŠã®é·ç§»ãæžãåºããããç°¡åã§ãã ãšããã§ãã»ãšãã©ã®å Žåãç¶æ
ã¯ã¢ããªã±ãŒã·ã§ã³ã®æ©èœã®ããžãã¯ãèšè¿°ããŸãã ãããããã©ã³ãžã·ã§ã³ã«ã€ããŠè©±ãå Žåããããã®æå³ã¯ãã°ãã°äœæ¥ã®éå§æã«äžæã§ãã ããã°ã©ã ã®ãšã©ãŒã¯ãã¢ããªã±ãŒã·ã§ã³ããããã®ã¢ã¯ã·ã§ã³çšã«èšèšãããŠããªãç¶æ
ã«ãããšãã«ã¢ã¯ã·ã§ã³ãå®è¡ããããšããäºå®ã®çµæã§ãã ããã«ãã¢ããªã±ãŒã·ã§ã³ãé©åãªç¶æ
ã«ããå Žåã§ããã¢ã¯ã·ã§ã³ãééã£ãæéã«å®è¡ãããå¯èœæ§ããããŸãã ãã®ãããªã¢ã¯ã·ã§ã³ã«ãããã¢ããªã±ãŒã·ã§ã³ã¯äžæãªç¶æ
ã«ãªããããã«ããããã°ã©ã ãç¡å¹ã«ãªãããæ£ããåäœããªããšããäºå®ã«ã€ãªãããŸãã ãã¡ãããå¿
èŠãããŸããã ã¹ããŒããã·ã³ã¯ããã®ãããªåé¡ã«å¯Ÿããåªãã察çã§ãã ããã«ãããçºçããå¯èœæ§ã®ããç¶æ³ãæ確ã«æå®ããããšãªããçºçããå¯èœæ§ã®ããå¢çãèšå®ãããããæªç¥ã®ç¶æ
ã«å°éããããšãé²ããŸãã ã¹ããŒããã·ã³ã®æŠå¿µã¯ãåæ¹åã®ããŒã¿ã¹ããªãŒã ã«é©ããŠããŸãã äžç·ã«ãã³ãŒãã®è€éãã軜æžããã·ã¹ãã ãç¹å®ã®ç¶æ
ã«ãªã£ãæ¹æ³ã«é¢ãã質åã«æ確ãªåçãæäŸããŸãã
JavaScriptã䜿çšããŠã¹ããŒããã·ã³ãäœæãã
ååãªè©±-ããã¯ããã°ã©ã ããæéã§ãã åãäŸã䜿çšããŸãã äžèšã®ãªã¹ãã«åºã¥ããŠã次ã®ã³ãŒãããå§ããŸãããã
const machine = { 'idle': { click: function () { ... } }, 'fetching': { success: function () { ... }, failure: function () { ... } }, 'error': { 'retry': function () { ... } } }
ç¶æ
ã¯ãªããžã§ã¯ãã«ãã£ãŠè¡šãããå¯èœãªå
¥åç¶æ
ä¿¡å·ã¯ãªããžã§ã¯ãã®ã¡ãœããã«ãã£ãŠè¡šãããŸãã ãã ããåæç¶æ
ã¯ããã«ã¯ãããŸããã äžèšã®ã³ãŒããå€æŽããŠã次ã®åœ¢åŒã«ããŸãã
const machine = { state: 'idle', transitions: { 'idle': { click: function() { ... } }, 'fetching': { success: function() { ... }, failure: function() { ... } }, 'error': { 'retry': function() { ... } } } }
æå³ã®ããç¶æ
ããã¹ãŠç¹å®ããããå
¥åä¿¡å·ãéä¿¡ããŠã·ã¹ãã ã®ç¶æ
ãå€æŽããæºåãæŽããŸãã ãããè¡ãã«ã¯ã次ã®2ã€ã®è£å©çãªæ¹æ³ã䜿çšããŸãã
const machine = { dispatch(actionName, ...payload) { const actions = this.transitions[this.state]; const action = this.transitions[this.state][actionName]; if (action) { action.apply(machine, ...payload); } }, changeStateTo(newState) { this.state = newState; }, ... }
dispatch
æ©èœã¯ãçŸåšã®ç¶æ
ã®é·ç§»ã®äžã«ãæå®ãããååã®ã¢ã¯ã·ã§ã³ããããã©ããã確èªããŸãã ãã®å Žåã圌女ã¯ãã®ã¢ã¯ã·ã§ã³ãåŒã³åºããåŒã³åºãäžã«è»¢éãããããŒã¿ã圌ã«æž¡ããŸãã ããã«ã
action
ãã³ãã©ã¯
machine
ãã³ã³ããã¹ããšããŠåŒã³åºãããããã
this.dispatch(<action>)
ã䜿çšããŠå¥ã®ã¢ã¯ã·ã§ã³ã
this.dispatch(<action>)
ã
this.dispatch(<action>)
this.changeStateTo(<new state>)
ã䜿çšããŠç¶æ
ãå€æŽãããã§ããŸãã
ãã®äŸã®ãŠãŒã¶ãŒãã¹ã«åŸã£ãŠããã£ã¹ãããããå¿
èŠãããæåã®ã¢ã¯ã·ã§ã³ã¯
click
ã§ãã ãã®ã¢ã¯ã·ã§ã³ã®ãã³ãã©ãŒã¯æ¬¡ã®ããã«ãªããŸãã
transitions: { 'idle': { click: function () { this.changeStateTo('fetching'); service.getData().then( data => { try { this.dispatch('success', JSON.parse(data)); } catch (error) { this.dispatch('failure', error) } }, error => this.dispatch('failure', error) ); } }, ... } machine.dispatch('click');
æåã«ããã·ã³ã®ç¶æ
ã
fetching
ãŸãã 次ã«ããµãŒããŒãžã®ãªã¯ãšã¹ããå®è¡ããŸãã promiseãè¿ã
getData
ã¡ãœãããæã€ãµãŒãã¹ããããšããŸãã ãã®ãããã¹ã解決ãããããŒã¿ãæ£åžžã«è§£æãããåŸã
succes
ã€ãã³ãããã£ã¹ãããããŸãã
ãã¹ãŠãæ£åžžã«é²è¡ããŠããéã 次ã«ã
success
ã¢ã¯ã·ã§ã³ãš
failure
ã¢ã¯ã·ã§ã³ãå®è£
ãã
fetching
ã¹ããŒã¿ã¹ã®å
¥åãèšè¿°ããå¿
èŠããããŸãã
transitions: { 'idle': { ... }, 'fetching': { success: function (data) { // this.changeStateTo('idle'); }, failure: function (error) { this.changeStateTo('error'); } }, ... }
以åã®ããã»ã¹ã«ã€ããŠèããå¿
èŠããèªåãæã£ãããšã«æ³šæããŠãã ããã ãŠãŒã¶ãŒããã¿ã³ãã¯ãªãã¯ããããšããHTTPãªã¯ãšã¹ãã§äœãèµ·ãããã¯æ°ã«ããŸããã ã¢ããªã±ãŒã·ã§ã³ã
fetching
ç¶æ
ã«ããããšã¯ããã£ãŠãããããã2ã€ã®ã¢ã¯ã·ã§ã³ã®ã¿ã衚瀺ãããããšãæåŸ
ããŠããŸãã ããã¯ãåé¢ããŠåäœããæ°ããã¢ããªã±ãŒã·ã§ã³ãšã³ãžã³ãäœæããããšã«å°ã䌌ãŠããŸãã
æåŸã«å¯ŸåŠããå¿
èŠãããã®ã¯ã
error
ç¶æ
ã§ãã ããã§ã³ãŒããäœæããŠåè©Šè¡ãå®è£
ãããšéåžžã«äŸ¿å©ã§ãããã®çµæããšã©ãŒãçºçããåŸãã¢ããªã±ãŒã·ã§ã³ãå埩ã§ããŸãã
transitions: { 'error': { retry: function () { this.changeStateTo('idle'); this.dispatch('click'); } } }
ããã§ã¯ã
click
ãã³ãã©ãŒã§æ¢ã«èšè¿°ãããŠããã³ãŒããã³ããŒããå¿
èŠããã
click
ã ãããåé¿ããã«ã¯ãäž¡æ¹ã®ã¢ã¯ã·ã§ã³ã§äœ¿çšå¯èœãªé¢æ°ãšããŠãã³ãã©ãŒã宣èšããããæåã«
idle
ç¶æ
ã«åãæ¿ããŠãã
click
ã¢ã¯ã·ã§ã³ãèªåã§ãã£ã¹ãããããå¿
èŠããã
click
ã
åäœç¶æ
ãã·ã³ã®å®å
šãªäŸã¯
ãCodePenãããžã§ã¯ãã«ãããŸãã
ã©ã€ãã©ãªã䜿çšããŠã¹ããŒããã·ã³ã管çãã
ã¹ããŒããã·ã³ãã³ãã¬ãŒãã¯ãReactãVueãAngularã®ãããã䜿çšããŠãæ©èœããŸãã åã®ã»ã¯ã·ã§ã³ã§èŠãããã«ãçŽç²ãªJSã«ã¹ããŒããã·ã³ãå®è£
ããããšã¯ããã»ã©å°é£ã§ã¯ãããŸããã ãã ãããããç¹æ®ãªã©ã€ãã©ãªã«å§ä»»ãããšããããžã§ã¯ãã®æè»æ§ãåäžããŸãã ã¹ããŒããã·ã³ã®å®è£
ã«é©ããã©ã€ãã©ãªã®äŸã«ã¯ã
Machina.jsããã³
XStateãå«ãŸããŸãã ãã ãããã®èšäºã§ã¯ãã¹ããŒããã·ã³ã®æŠå¿µãå®è£
ããReduxã«äŒŒãã©ã€ãã©ãªã§ãã
Stentã«ã€ããŠèª¬æããŸãã
ã¹ãã³ãã¯ãã¹ããŒããã·ã³ã³ã³ããã®å®è£
ã§ãã ãã®ã©ã€ãã©ãªã¯ãReduxããã³Redux-Sagaãããžã§ã¯ãããã®ããã€ãã®ã¢ã€ãã¢ã«åŸããŸãããç§ã®æèŠã§ã¯ã䜿ããããããã³ãã¬ãŒãã«ããå¶çŽãå°ãªããªããŸãã æåã«ãããžã§ã¯ãã®ããã¥ã¡ã³ããäœæãã次ã«ã³ãŒããäœæãããšããäºå®ã«åºã¥ãã
ã¢ãããŒãã䜿çšããŠéçºãããŠããŸãã ãã®ã¢ãããŒãã«ç¶ããŠãAPIã®èšèšã®ã¿ãæ°é±éè¡ããŸããã ã©ã€ãã©ãªãèªåã§æžããã®ã§ãReduxããã³Fluxã¢ãŒããã¯ãã£ã䜿çšããŠééããåé¡ãä¿®æ£ããæ©äŒããããŸããã
ã¹ãã³ãã§ã®ã¹ããŒããã·ã³ã®äœæ
ã»ãšãã©ã®å Žåãã¢ããªã±ãŒã·ã§ã³ã¯å€ãã®æ©èœãå®è¡ããŸãã ãã®çµæã1å°ã®ãã·ã³ã ããå®è¡ããããšã¯ã§ããŸããã ãããã£ãŠãã¹ãã³ãã䜿çšãããšãå¿
èŠãªæ°ã®ãã·ã³ãäœæã§ããŸãã
import { Machine } from 'stent'; const machineA = Machine.create('A', { state: ..., transitions: ... }); const machineB = Machine.create('B', { state: ..., transitions: ... });
åŸã§
Machine.get
ã¡ãœããã䜿çšããŠãããã®ãã·ã³ã«ã¢ã¯ã»ã¹ã§ããŸãã
const machineA = Machine.get('A'); const machineB = Machine.get('B');
ãã·ã³ãã¬ã³ããªã³ã°ããžãã¯ã«æ¥ç¶ãã
ç§ã®å Žåã®ã¬ã³ããªã³ã°ã¯ReactããŒã«ã䜿çšããŠè¡ãããŸãããä»ã®ã©ã€ãã©ãªã䜿çšããããšãã§ããŸãã ãã¹ãŠã¯ãã¬ã³ããªã³ã°ãéå§ããã³ãŒã«ããã¯ãåŒã³åºãããšã§ãã ç§ãäœæããã©ã€ãã©ãªã®æåã®æ©èœã®1ã€ã¯ã
connect
æ©èœã§ããã
import { connect } from 'stent/lib/helpers'; Machine.create('MachineA', ...); Machine.create('MachineB', ...); connect() .with('MachineA', 'MachineB') .map((MachineA, MachineB) => { ... });
ã©ã®ãã·ã³ãæäœãããããã·ã¹ãã ã«éç¥ããååã瀺ããŸãã
map
ã¡ãœããã«æž¡ãã³ãŒã«ããã¯ã¯ããã«åŒã³åºãããããã¯1åè¡ãããŸãã ãã®åŸãããããã®ãã·ã³ã®ç¶æ
ãå€åãããã³ã«åŒã³åºãããŸãã ãããã¬ã³ããªã³ã°é¢æ°ãåŒã³åºãå Žæã§ãã ãã®å Žæã§ã¯ãæ¥ç¶ããããã·ã³ã«çŽæ¥ã¢ã¯ã»ã¹ã§ããããããã·ã³ãšãã®ã¡ãœããã®çŸåšã®ç¶æ
ãååŸã§ããŸãã ãã®ã©ã€ãã©ãªã«ã¯ãäžåºŠã ãåŒã³åºãå¿
èŠãããã³ãŒã«ããã¯ãåŠçããããã«äœ¿çšããã
mapOnce
ã¡ãœãããšããã®æåã®1åéãã®ã³ãŒã«ããã¯ã®å®è¡ãã¹ãããããããã®
mapSilent
ãŸãã
䟿å®äžãReactãšã®çµ±åã®ããã«è£å©é¢æ°ããšã¯ã¹ããŒããããŠããŸãã ããã¯ã
æ¥ç¶ïŒmapStateToPropsïŒ Reduxã³ã³ã¹ãã©ã¯ãã«éåžžã«äŒŒãŠããŸãã
import React from 'react'; import { connect } from 'stent/lib/react'; class TodoList extends React.Component { render() { const { isIdle, todos } = this.props; ... } }
ã¹ãã³ãã¯ã³ãŒã«ããã¯ãããªããžã§ã¯ããåãåãããšãæåŸ
ããŸãã ã€ãŸããReactã³ã³ããŒãã³ãã«
props
ãšããŠéä¿¡ããããªããžã§ã¯ãã
ã¹ãã³ãã®ã³ã³ããã¹ãã«ãããç¶æ
ãšã¯äœã§ããïŒ
ãããŸã§ã®ãšãããç¶æ
ã¯åçŽãªæååã§ãã æ®å¿µãªãããçŸå®ã®äžçã§ã¯ãéåžžã®æåå以å€ã®ç¶æ
ã§ä¿åããå¿
èŠããããŸãã ããããã¹ãã³ãç¶æ
ãããããã£ãæã€ãªããžã§ã¯ãã§ããçç±ã§ãã äºçŽãããŠããããããã£ã¯
name
ã®ã¿ã§ãã ãã以å€ã¯ãã¹ãŠã¢ããªã±ãŒã·ã§ã³åºæã®ããŒã¿ã§ãã äŸïŒ
{ name: 'idle' } { name: 'fetching', todos: [] } { name: 'forward', speed: 120, gear: 4 }
Stentã®ç§ã®çµéšã§ã¯ãç¶æ
ãªããžã§ã¯ãã倧ãããªãããããšããããããããã®è¿œå ããããã£ãåŠçã§ããå¥ã®ç¶æ
ãã·ã³ãå¿
èŠã«ãªãããšãããããŸãã ããŸããŸãªç¶æ
ãç¹å®ããã«ã¯æéãããããŸãããããã¯ç®¡çã容æãªã¢ããªã±ãŒã·ã§ã³ãäœæããäžã§å€§ããªåé²ã ãšæããŸãã ããã¯ãã·ã¹ãã ã®åäœãäºåã«èšç»ããå°æ¥ã®ã¢ã¯ã·ã§ã³ã®ããã®ã¹ããŒã¹ãæºåããè©Šã¿ã®ãããªãã®ã§ãã
ã¹ããŒããã·ã³ãæäœãã
ææã®åé ã«ç€ºããäŸãšã»ãŒåãæ¹æ³ã§ãã¹ãã³ãã䜿çšããå Žåããã·ã³ã®å¯èœãªïŒæçµïŒç¶æ
ãèšå®ããå¯èœãªå
¥åä¿¡å·ãèšè¿°ããå¿
èŠããããŸãã
import { Machine } from 'stent'; const machine = Machine.create('sprinter', { state: { name: 'idle' }, // transitions: { 'idle': { 'run please': function () { return { name: 'running' }; } }, 'running': { 'stop now': function () { return { name: 'idle' }; } } } });
run
ã¢ã¯ã·ã§ã³ã
run
ããåæç¶æ
idle
ããããŸãã ãã·ã³ã
running
ç¶æ
ã«ãªã£ããã
stop
ã¢ã¯ã·ã§ã³ãéå§ããŠããã·ã³ã
idle
ç¶æ
ã«æ»ãããšãã§ããŸãã
äžèšã®äŸã®ãã«ããŒé¢æ°
dispatch
ããã³
changeStateTo
æãåºããŠãã ããã ã¹ãã³ãã¯åãæ©èœãæäŸããŸãããã©ã€ãã©ãªå
ã«é ãããŠãããããèªåã§å¯ŸåŠããå¿
èŠã¯ãããŸããã 䟿å®äžã
transitions
ããããã£ã«åºã¥ããŠãStentã¯ä»¥äžãçæããŸãã
- ãã·ã³ãäœããã®ç¶æ
ã«ãããã©ããã確èªãããã«ããŒã¡ãœããã ãããã£ãŠã
idle
ç¶æ
ã«ãªããšisIdle()
ã¡ãœãããäœæããã running
ç¶æ
ã«ãªããšisIdle()
ã¡ãœãããäœæãããŸãã
- ã€ãã³ãããã£ã¹ãããããããã®ãã«ããŒã¡ãœããïŒ
runPlease()
ããã³stopNow()
ãã®çµæããã®äŸã§ã¯æ¬¡ã®æ§æãå©çšã§ããŸãã
machine.isIdle(); // machine.isRunning(); // machine.runPlease(); // machine.stopNow(); //
èªåçæãããã¡ãœããããµãŒãã¹
connect
æ©èœãšçµã¿åãããããšã«ãããæ¢è£œã®ãœãªã¥ãŒã·ã§ã³ãæãä»ãããšãã§ããŸãã ãŠãŒã¶ãŒã¯ããã·ã³ã®å
¥åãšç¶æ
ã®å€åã«ã€ãªããã¢ã¯ã·ã§ã³ã«åœ±é¿ãäžããŸãã ç¶æ
ã®å€åã«ããã
connect
æž¡ããããããã³ã°é¢æ°ãåŒã³åºãããç¶æ
ã®å€åã«é¢ããéç¥ãåãåããŸãã 次ã«ãããŒã¿ãç»é¢ã«åºåãããŸãã
å
¥åããŒã¿ãšã¢ã¯ã·ã§ã³ãã³ãã©ãŒ
ããããããã®äŸã§æãéèŠãªã®ã¯ã¢ã¯ã·ã§ã³ãã³ãã©ãŒã§ãã ããã¯ãã·ã¹ãã ãå
¥åããŒã¿ããã³å€æŽãããç¶æ
ã«ã©ã®ããã«åå¿ãããã説æãããããã»ãšãã©ã®ã¢ããªã±ãŒã·ã§ã³ããžãã¯ãèšè¿°ããå Žæã§ãã Reduxã®èšèšäžã«è¡ãããæãæåããã¢ãŒããã¯ãã£ã®æ±ºå®
ã¯ãreduceré¢æ°ã®äžå€æ§ãšåçŽã
ã§ãããšæã
æã
ãŸã ã æ¬è³ªçã«ãã¹ãã³ãã¢ã¯ã·ã§ã³ãã³ãã©ãŒã¯åããã®ã§ãã ãã³ãã©ãŒã¯çŸåšã®ç¶æ
ãšã¢ã¯ã·ã§ã³ã«é¢é£ä»ããããããŒã¿ãåãåãããã®åŸæ°ããç¶æ
ãè¿ãå¿
èŠããããŸãã ãã³ãã©ãŒãäœãè¿ããªãå ŽåïŒ
undefined
ïŒããã·ã³ã®ç¶æ
ã¯å€æŽãããŸããã
transitions: { 'fetching': { 'success': function (state, payload) { const todos = [ ...state.todos, payload ]; return { name: 'idle', todos }; } } }
ãªã¢ãŒããµãŒããŒããããŒã¿ãããŠã³ããŒããããšããŸãã ãããè¡ãã«ã¯ããªã¯ãšã¹ããå®è¡ãããã·ã³ã
fetching
ç¶æ
ã«ããŸãã ãµãŒããŒããããŒã¿ãå°çãããšããã«ã
success
ã€ãã³ããçºç
success
ãŸãã
machine.success({ label: '...' });
ãã®åŸã
idle
ç¶æ
ã«æ»ããäžéšã®ããŒã¿ã
todos
é
åãšããŠä¿åããŸãã ã¢ã¯ã·ã§ã³ãã³ãã©ãæ§æããããã®ãªãã·ã§ã³ãããã€ããããŸãã æåã®æãåçŽãªã±ãŒã¹ã¯ãæ°ããç¶æ
ã«ãªãåçŽãªæååã§ã®äœæ¥ã§ãã
transitions: { 'idle': { 'run': 'running' } }
ããã«ç€ºãããŠããã®ã¯ã
run()
ã¢ã¯ã·ã§ã³ã䜿çšãã
{ name: 'idle' }
ç¶æ
ãã
{ name: 'running' }
ç¶æ
ãžã®é·ç§»ã§ãã ãã®ã¢ãããŒãã¯ãç¶æ
ã«è¿œå ã®ããŒã¿ããªããç¶æ
éã®åæé·ç§»ã䜿çšãããå Žåã«åœ¹ç«ã¡ãŸãã ãããã£ãŠãç¶æ
ãªããžã§ã¯ãã«ä»ã®äœããæ ŒçŽãããŠããå Žåãç¶æ
éã®ãã®ãããªé·ç§»ã¯ããã®ãããªè¿œå ããŒã¿ãç Žå£ããŸãã åæ§ã«ãç¶æ
ãªããžã§ã¯ããçŽæ¥æž¡ãããšãã§ããŸãã
transitions: { 'editing': { 'delete all todos': { name: 'idle', todos: [] } } }
ããã§ã¯ã
deleteAllTodos
ã¢ã¯ã·ã§ã³ã䜿çšããŠã
editing
ç¶æ
ãã
idle
ãžã®ç§»è¡ã芳å¯ã§ããŸãã
ãã³ãã©ãŒé¢æ°ã¯æ¢ã«èŠãŠãããã¢ã¯ã·ã§ã³ãã³ãã©ãŒã®æåŸã®ããŒãžã§ã³ã¯ãžã§ãã¬ãŒã¿ãŒé¢æ°ã§ãã
Redux-Sagaãããžã§ã¯ãã¯ããã®ã¡ã«ããºã ã®ã€ããªãã®ãŒçåºæ¿æºã«ãªããŸããã次ã®ããã«ãªããŸãã
import { call } from 'stent/lib/helpers'; Machine.create('app', { 'idle': { 'fetch data': function * (state, payload) { yield { name: 'fetching' } try { const data = yield call(requestToBackend, '/api/todos/', 'POST'); return { name: 'idle', data }; } catch (error) { return { name: 'error', error }; } } } });
ãžã§ãã¬ãŒã¿ãŒã®çµéšããªãå Žåãäžèšã®ã³ãŒããã©ã°ã¡ã³ãã¯å°ãäžæè°ã«èŠãããããããŸããã ãã ããJavaScriptãžã§ãã¬ãŒã¿ãŒã¯åŒ·åãªããŒã«ã§ãã 圌ãã®å©ããåããŠãã¢ã¯ã·ã§ã³ãã³ãã©ãäžæåæ¢ããç¶æ
ãæ°åå€æŽããéåæã¡ã«ããºã ãåŠçã§ããŸãã
çºé»æ©å®éš
Redux-Sagaã«åããŠäŒã£ããšããéåææäœããµããŒãããããã®éåžžã«è€éãªæ¹æ³ãæ瀺ããããšã«ããŸããã å®éãããã¯
ã³ãã³ããã³ãã¬ãŒãã®éåžžã«æ©ç¥ã«å¯ãã å®è£
ã§ãã ãã®ãã³ãã¬ãŒãã®äž»ãªå©ç¹ã¯ãã¡ã«ããºã ãšãã®å®éã®å®è£
ã®èª²é¡ãå
±æããŠããããšã§ãã
ã€ãŸããã·ã¹ãã ã«å¿
èŠãªããšãäŒããŸããããããã©ã®ããã«è¡ãããã¹ããã«ã€ããŠã¯è©±ããŸããã Matt Hicks
ã«ããäžé£ã®è³æã¯ããããç解ããã®ã«åœ¹ç«ã¡ãŸããã åãã¢ã€ãã¢ãã¹ãã³ãã«ãããããŸããã ã·ã¹ãã ã«å¶åŸ¡ã移ããå¿
èŠãªãã®ãéç¥ããŸãããå®éã«ã¯è¡ããŸããã ã¢ã¯ã·ã§ã³ãå®äºãããšãå¶åŸ¡ãæ»ããŸãã
çŸæç¹ã§ã·ã¹ãã ã«è»¢éã§ãããã®ã¯æ¬¡ã®ãšããã§ãã
- ãã·ã³ã®ç¶æ
ãå€æŽããããã®ç¶æ
ãªããžã§ã¯ãïŒãŸãã¯æååïŒã
- è£å©çãª
call
é¢æ°ïŒåæé¢æ°ãåããŸããåæé¢æ°ã¯ãpromiseãŸãã¯ä»ã®ãžã§ãã¬ãŒã¿ãŒé¢æ°ãè¿ãé¢æ°ã§ãïŒã ãã®ãããªé¢æ°ãæž¡ãããšã«ãããåºæ¬çã«ã·ã¹ãã ã«æ¬¡ã®ããã«äŒããŸããããã®é¢æ°ãå®è¡ããéåæã®å Žåã¯åŸ
æ©ããŸãã äœæ¥ãå®äºãããããã«çµæããç¥ãããã ãããã
- ãã«ããŒé¢æ°ã®
wait
ïŒå¥ã®ã¢ã¯ã·ã§ã³ãè¡šãæååãåãåããŸãïŒã ãã®ãµãŒãã¹é¢æ°ã䜿çšããå Žåããã³ãã©ãŒãäžæåæ¢ããå¥ã®ã¢ã¯ã·ã§ã³ã®ãã£ã¹ããããåŸ
ã¡ãŸãã
äžèšã®äŸã瀺ãé¢æ°ã次ã«ç€ºããŸãã
const fireHTTPRequest = function () { return new Promise((resolve, reject) => { // ... }); } ... transitions: { 'idle': { 'fetch data': function * () { yield 'fetching'; // { name: 'fetching' } yield { name: 'fetching' }; // , // // getTheData checkForErrors const [ data, isError ] = yield wait('get the data', 'check for errors'); // , // fireHTTPRequest const result = yield call(fireHTTPRequest, '/api/data/users'); return { name: 'finish', users: result }; } } }
, , , . , Stent .
Redux Stent
â
Redux ( Flux) , . , , . , . , , , .
Stent . :
const machine = Machine.create('todo-app', { state: { name: 'idle', todos: [] }, transitions: { 'idle': { 'add todo': function (state, todo) { ... } } } }); machine.addTodo({ title: 'Fix that bug' });
machine.addTodo
, . , : , . React
addToDo
. , . . .
â
, Redux . Redux, , . , , , ? â Redux? , , , - . , , . , - , .
, ? ?
Redux, , . , . Stent , , . äŸïŒ
const machine = Machine.create('app', { state: { name: 'idle' }, transitions: { 'idle': { 'run': 'running', 'jump': 'jumping' }, 'running': { 'stop': 'idle' } } }); // machine.run(); // , // // running stop. machine.jump();
, .
Redux, Flux, . , Redux-, , , , . , , , , , . , , , .
ãŸãšã
, â , . , , , . . , , , â . , â . â , â . - , .
芪æãªãèªè
ïŒ ?
