componentWillMountãpromiseãè¿ãããšãã§ãããã®åå¿ã«ãã£ãŠãã®promiseã解決ããããŸã§ã¬ã³ããªã³ã°ãé 延ããå Žåã¯ãå圢ã®äœããæ§ç¯ããããã»ã¹ãå€§å¹ ã«å®¹æã«ãªããŸãã ç§ã¯react-routerãrrouterã§ãã®ãããªããšãããããšããŠããã®ãèŠãŠããŸããããã«ãŒã¿ãŒã¢ãžã¥ãŒã«ã§ã¯ãªãåã³ã³ããŒãã³ãã«ãã®è²¬ä»»ãäžããæ¹ãçã«ããªã£ãŠããŸãã
ããããŸã ååšããªãäž»ãªçç±ïŒç§ã¯ä¿¡ããŠããŸãïŒã¯ãã¯ã©ã€ã¢ã³ãåŽã§ã¯ãã¬ã³ããªã³ã°ã延æããã®ã§ã¯ãªããåºæ¬çã«åžžã«äœããã®è² è·ã€ã³ãžã±ãŒã¿ãŒã衚瀺ããããšããããšã§ãã ïŒããã«ãããã³ãŒããå€§å¹ ã«è€éã«ãªããŸãããããããããã«å¯ŸåŠã§ããŸããïŒ
ãããªãã§ã¯è§£æ±ºããã®ãé£ãã2ã€ã®ã±ãŒã¹ããããŸãïŒ
react-asyncã¯ããã¡ã€ããŒãšãã£ãã·ã¥ã«é¢ãããããã®åé¡ã解決ããŸãã ããã§ããŸããããŸãããç§ã®èŠè§£ã§ã¯ããããã¯ã³ã¢ã§ãã解決ã§ããªãåé¡ã解決ããããã®åãªããããã¯ããœãªã¥ãŒã·ã§ã³ã§ãã
@fdecampredonã¯ã componentWillMount
ã¯éåæã§ãããããã«ã¯äœãè¿ããªãããšèšã£ãŠããŸããReactã¯ãäœã衚瀺ãããªããªããŸã§äœãã¬ã³ããªã³ã°ããã®ã§ããããã ãããããªãããŸã ããŒã¿ããªãã®ã«ã¬ã³ããªã³ã°ã§äœãè¿ããªãã®ã¯ãªãã§ããïŒ ïŒãããç§ã¯ãµãŒããŒãµã€ããååŸããŸãïŒãŸãã componentWillMount
çºç ²ããåã«å°éå
·ãå€æŽãããå Žåã¯ã©ããªããŸããïŒ
å人çã«ã¯ãã³ã³ããŒãã³ããå®éã«åé¢ããããã©ãã¯ããã¯ã¹ã§ãããããŒãã€ã³ãžã±ãŒã¿ãŒãå®è£
ããŠããªãéãã componentWillMount
éã«éåæèŠæ±ããã£ã¹ãããããã®ã¯ééã£ãŠããããã§ãã ç§ãç解ããŠããéããReactã³ã³ããŒãã³ããåŸæ¥ã®OOPã€ã³ã¹ã¿ã³ã¹ãšééããªãã§ãã ããã æè¯ã®å ŽåãReactã³ã³ããŒãã³ãã¯ãå°éå
·ã®ããŒã¿ãèŠèŠåããããã®ããŒã«ã§ããã€ã³ã¿ã©ã¯ãã£ãã§ããå Žåã¯ãç¶æ
ã衚瀺ãããå¯èœæ§ããããŸãã ããã¯ãã¥ãŒã§ããããã¥ãŒãšã¢ãã«ã§ã¯ãããŸããã
ç§ã®è³ã«ã¯ãããã¯åé¡ã®ããã«èãããŸããReactã³ã³ããŒãã³ãã¯éåæãªã¯ãšã¹ãããã£ã¹ãããããã³ã³ããŒãã³ãã§ã¯ãªãããã¹ãŠã®ããŒã¿ããã§ãããããã®ããŒã¿ã®æºåãã§ãããã React.renderComponent
ãåŒã³åºããŸãã ã¯ã©ã€ã¢ã³ãåŽãšãµãŒããŒåŽã§åããœãªã¥ãŒã·ã§ã³ã ãŸããéåæãªã¯ãšã¹ãã倱æããå Žåã«ãéžæããçµæã§äžæ¢ããããšãã§ããŸãã
ç§ãäœãã誀解ããå Žåã¯ãé æ ®ãªãç§ã解éããŠãã ããããã ããReactã³ã³ããŒãã³ãã¯ãåãªããã¥ãŒãšããŠæå³ãããŠããå Žåã¯ããã¥ãŒããã³ã¢ãã«ãšããŠæ±ã£ãŠããããã§ãã
@fdecampredonã¯ãcomponentWillMountã¯éåæã§ãããããã«ã¯äœãè¿ããªãããšèšã£ãŠããŸã
ç§ã¯ãã¹ãŠã®ã±ãŒã¹ã«ã€ããŠèããŠããªãã£ãããšãèªããªããã°ãªããŸãã^^ã
ãã®æ©èœã¯ããããã¬ãã«ã³ã³ããŒãã³ããåããŠããŠã³ããããšãã«ã®ã¿åœ¹ç«ã¡ãŸãããã以å€ã®å Žåã¯ãã»ãšãã©ã®ãã£ã¹ãã§ããŒããŒã€ã³ãžã±ãŒã¿ãŒã衚瀺ããå¿
èŠããããŸãã
å人çã«ã¯ãã³ã³ããŒãã³ããå®éã«åé¢ããããã©ãã¯ããã¯ã¹ã§ãããããŒãã€ã³ãžã±ãŒã¿ãŒãå®è£ ããŠããªãéããcomponentWillMountäžã«éåæèŠæ±ããã£ã¹ãããããã®ã¯ééã£ãŠããããã§ããç§ãç解ããŠããéããReactã³ã³ããŒãã³ããåŸæ¥ã®OOPã€ã³ã¹ã¿ã³ã¹ãšééããªãã§ãã ãããæè¯ã®å ŽåãReactã³ã³ããŒãã³ãã¯ãå°éå ·ã®ããŒã¿ãèŠèŠåããããã®ããŒã«ã§ããã€ã³ã¿ã©ã¯ãã£ãã§ããå Žåã¯ãç¶æ ã衚瀺ãããå¯èœæ§ããããŸããããã¯ãã¥ãŒã§ããããã¥ãŒãšã¢ãã«ã§ã¯ãããŸããã
ããæå³ãŸãã¯ä»ã®æ¹æ³ã§ã¯ã Fluxãµã³ãã«ã§è¡ãããããã«ãããããã¬ãã«ãã³ã³ããŒãã³ããããŒã¿ãååŸã§ããããã«ããå¿
èŠããã
ãã®ãµã³ãã«ã§ã¯ãââtodoã®ãªã¹ãã®ååŸã¯åææäœã§ãããããéåžžã«åçŽã§ããåææäœãè¡ãããªãã£ãå ŽåããµãŒããŒã§äºåã¬ã³ããªã³ã°ãè¡ããšãããŒã¿ãªãã§åããŠã¬ã³ããªã³ã°ãããŸãïŒäºåã¬ã³ããªã³ã°ã倱ãããŸãïŒããµãŒããŒããã®ããŒã¯ã¢ããïŒã
1ã€ã®ãã¥ãŒéå±€ã«ãã£ãŠ1ã»ããã®ããŒã¿ã衚瀺ãããåçŽãªã¢ããªã±ãŒã·ã§ã³ã®å Žåã§ããããã»ã©åé¡ã¯ãããŸãããããŒã¿ãããªããŒãããŠããã¹ãã¢ã®åæããããã£ãç¶æã§ããŸãã
ããã§ãã¢ããªã±ãŒã·ã§ã³å
šäœã§åå©çšããè€æ°ã®ã¢ãžã¥ãŒã«ã§æ§æãããã¢ããªã±ãŒã·ã§ã³ã®å Žåããããã®ã¢ãžã¥ãŒã«ããç°ãªãã¹ãã¢ã§ããµãã¹ã¯ã©ã€ããã§ããïŒããŒã¿ã®ãã§ãããæ
åœããïŒåå¥ã®ã¢ããªã±ãŒã·ã§ã³ãšããŠåŠçã§ããããã«ããããšæããŸãã
ããããç§ã¯ç©äºãééã£ãæ¹æ³ã§ç解ããŠãããããããŸããããWebã®åšãã®ããã€ãã®è°è«/ãµã³ãã«ã¯ãã©ããã«äœããæ¬ ããŠãããšç§ã«æãããŸãïŒ
willTransitionTo
ã§åæ§ã®ã¡ã«ããºã ãä¿é²ããããã€ãã®è°è«ã¯ç§ã«é©åãªè§£æ±ºçã誰ãæã£ãŠããªãããã«æããããŸãã@fdecampredonæ確ã«ããããã«ãreact-nested-routerã®willTransitionTo
ã®ç®çã¯ãããŒã¿ãããŒãããããšã§ã¯ãããŸãããç¹ã«ããã®ã¡ãœããããpromiseãè¿ããšãæ°ããUIã®ã¬ã³ããªã³ã°ãå®éã«ãããã¯ãããããã§ãã絶察ã«å¿
èŠãªå Žåãé€ããŠã
@fdecampredon誰ãããŸã ç©äºãç解ããããšããŠããã®ã§ã誰ã決å®çãªçããæã£ãŠããªããŠãç§ã¯é©ããªãã§ãããã ããããFacebookã®éçºè ã¯ããã«äœåºŠãééããã«éããªããšæããŸãã
ããã«é¢ããæŽæ°ã¯ãããŸããïŒ Reactã®æ¢çŽ¢ãå§ããã°ããã§ãããã«ããã«ééããŸãã å€ãã®äººãå圢ã¢ããªãæ§ç¯ããããã®è§£æ±ºçãšããŠReactãæšå¥šããŠããŸãããããã解決ãããªãéããããã¯åã«ä»äºãæãéããããšãã§ããªããšæããŸãã
ç§ã®è³ã«ã¯ãåé¡ã®ããã«èãããŸãããReactã³ã³ããŒãã³ãã¯éåæãªã¯ãšã¹ãããã£ã¹ãããããã³ã³ããŒãã³ãã§ã¯ãªãããã¹ãŠã®ããŒã¿ããã§ãããããã®ããŒã¿ã®æºåãã§ããããReact.renderComponentãåŒã³åºããŸãã ã¯ã©ã€ã¢ã³ãåŽãšãµãŒããŒåŽã§åããœãªã¥ãŒã·ã§ã³ã ãŸããéåæãªã¯ãšã¹ãã倱æããå Žåã«ãéžæããçµæã§äžæ¢ããããšãã§ããŸãã
ç§ãäœãã誀解ããå Žåã¯ãé æ ®ãªãç§ã解éããŠãã ããããã ããReactã³ã³ããŒãã³ãã¯ãåãªããã¥ãŒãšããŠæå³ãããŠããå Žåã¯ããã¥ãŒããã³ã¢ãã«ãšããŠæ±ã£ãŠããããã§ãã
ãããåœãŠã¯ãŸãå ŽåãReactã¯ãããã«ç°ãªããã³ãã¬ãŒããœãªã¥ãŒã·ã§ã³/ãã¥ãŒã¬ã€ã€ãŒã«ãããŸããã ãããŠããã®ãããªå¯èœæ§ãããã®ã§ãããã¯æ®å¿µã§ãã @fdecampredonãè€æ°ã®ã¢ãžã¥ãŒã«ã§æ§æãããè€éãªã¢ããªã±ãŒã·ã§ã³ã«ã€ããŠèšåããŠãããšããç§ã¯æ¬åœã«ç解ããŠããŸãã Reactã¯ããã«æé©ã§ãã
ãã®ã¢ãããŒãã¯ãã³ã³ããŒãã³ãããã¥ãŒããã³ã¢ãã«ãšããŠæ±ãããšãæå³ãããšã¯æããŸããã Fluxã¢ãŒããã¯ãã£ãèŠããšãïŒã¹ãã¢ããã®ïŒããŒã¿ã衚瀺ããã ãã§ãªãããŠãŒã¶ãŒã®æäœã«åºã¥ããŠã¢ã¯ã·ã§ã³ãåŒã³åºã_controller-views_ã®æç¹ã§Reactã³ã³ããŒãã³ããèããŠããŸãã ãããŠãã¢ã¯ã·ã§ã³ã¯ã¹ãã¢ïŒ=ã¢ãã«ïŒãæŽæ°ããŸãã ç§ã«ã¯ãããã¯æãããªMVCã¢ãŒããã¯ãã£ã®ããã«èãããŸãã
åé¡ã¯ãã¹ãã¢ã«å
¥åããæåã®ã¢ã¯ã·ã§ã³ã«ãããŸãã ã¯ã©ã€ã¢ã³ãåŽã§ã¯ãæšå¥šãããŠããããã«componentDidMount()
ã¡ãœããããã¢ã¯ã·ã§ã³ãåŒã³åºãããšãã§ããã®ã¯ããªãç°¡åã§ãã äžæ¹ããµãŒããŒåŽã§ã¯ãã¢ã¯ã·ã§ã³ãçµäºããŠã¹ãã¢ã«ããŒã¿ãå
¥åããããŸã§ã¬ã³ããªã³ã°ãé
ãããç¹å¥ãªå Žæãšäœããã®ã¡ã«ããºã ãæ¬åœã«å¿
èŠã§ãã
çŸæç¹ã§ã¯ãå¯äžã®æ¹æ³ã¯React-async / Fibers + Fluxã§ããããã«æãããŸãã Fluxã®è¯ããšããã¯ãã³ã³ããŒãã³ãã®ç¶æ ããµãŒããŒããã¯ã©ã€ã¢ã³ãã«è»¢éããããã«äººå·¥çãªãã£ãã·ã¥ãå¿ èŠãšããªãããšã§ãïŒå ã®react-asyncã®äŸã§è¡ãããããã«ïŒãã¹ãã¢ãåæåããŠããã htmlããŒã¯ã¢ãããæã€ã¯ã©ã€ã¢ã³ãïŒãã®äŸãåç §ïŒã
ãããããã®è§£æ±ºçã¯ç¢ºãã«_hackish_ã§ãã
éåæã§ããcomponentWillMountã§ããå¿ èŠã¯å¿ ããããªããšæããŸãã ã©ã€ããµã€ã¯ã«ã€ãã³ãã§ããå¿ èŠããããã©ããããããããŸããã æ¬åœã®åé¡ã¯ããµãŒããŒåŽã§ã¯ããã¹ãŠãæååã«ã¬ã³ããªã³ã°ããããŸã§ãã³ã³ããŒãã³ãããªãŒãåæããæ¹æ³ããªãããšã§ãã
ããã解決ããããã®ç§ã®çæ³çãªè§£æ±ºçã¯ãã³ã³ããŒãã³ãããªãŒãæ§ç¯ããã ãã®ãã¬ã³ããªã³ã°ããèš±å¯ããããšã§ãããã®åŸãããªãŒããã©ããŒã¹ããŠãè¿œå ã®ããŒã¿ãå¿ èŠãªã³ã³ããŒãã³ããèŠã€ããéåæã§ããå€ãã®ããŒã¿ãããŒãããŠãåã¬ã³ããªã³ã°ãã§ããããã«ãªããŸãã ããã®ã³ã³ããŒãã³ãã®ãµãããªãŒãäœæããããŒã¯ã¢ããããã©ãã·ã¥ããæºåãã§ãããããã®ããªãŒãæååã«å€æã§ããããã«ããŸãã
ããã¯ããã©ãŠã¶ãŒã§å®è¡ã§ããããšãè€è£œããŸããå¿ èŠã«å¿ããŠåã¬ã³ããªã³ã°ã§ããä»®æ³DOMãçšæããŸãã éãã¯ããã©ãŠã¶ãŒã§ã¯DOMã®æŽæ°ãæé»çã«è¡ãããå¯èœæ§ãããããšã§ãã ãµãŒããŒã§ã¯ãéåæããŒã¿ã«åºã¥ããŠä»®æ³DOMã®æŽæ°ãå®è¡ã§ããããã«ãæååã«ã¬ã³ããªã³ã°ããã¿ã€ãã³ã°ãæ瀺ããå¿ èŠããããŸãã
ããã解決ããããã®ç§ã®çæ³çãªè§£æ±ºçã¯ãã³ã³ããŒãã³ãããªãŒãæ§ç¯ããã ãã®ãã¬ã³ããªã³ã°ããèš±å¯ããããšã§ãããã®åŸãããªãŒããã©ããŒã¹ããŠãè¿œå ã®ããŒã¿ãå¿ èŠãªã³ã³ããŒãã³ããèŠã€ããéåæã§ããå€ãã®ããŒã¿ãããŒãããŠãåã¬ã³ããªã³ã°ãã§ããããã«ãªããŸãã ããã®ã³ã³ããŒãã³ãã®ãµãããªãŒãäœæããããŒã¯ã¢ããããã©ãã·ã¥ããæºåãã§ãããããã®ããªãŒãæååã«å€æã§ããããã«ããŸãã â @mridgway
ãããããã¯ããã ããã çŸåšããµãŒããŒåŽã§ã³ã³ããŒãã³ãã2åã¬ã³ããªã³ã°ããããšã¯ãåé¿çãšããŠäœ¿çšã§ããŸãã
Reactå
ã§ãµããŒãããããã®ã®äŸãšããŠreact-nexusãåç
§ããããšæããŸãã ããã¯åºæ¬çã«mountComponent
åäœãæžãçŽãããã®ã§ãããå®éã«DOMã«ããŠã³ãããããæååãæžã蟌ãã ãããã«ã³ã³ããŒãã³ãããªãŒãæ§ç¯ããç¹ãç°ãªããŸãã ããã«ãããã³ã³ããŒãã³ãããªãŒããã©ããŒã¹ããããªãŒã®æ§ç¯äžã«éåæã¡ãœãããå®è¡ã§ããŸãã ãã®å®è£
ã®åé¡ã¯ãæåã®ããªãŒãç Žæ£ããŠããããšã«ããReact.renderToString
åŒã³åºãããšã§ããããã®äºåã¬ã³ããªã³ã°ããªãŒãååŸããŠã¬ã³ããªã³ã°/ããŠã³ããããšäŸ¿å©ã§ãã
ç§ã¯ã³ã¢å
ã§ããã«åãçµãã€ããã§ãããããã€ãã®ãã€ã³ã¿ãŒãå¿
èŠã«ãªããŸãã èŠä»¶ã®1ã€ã¯ãéåæã§åé¡ãçºçããªãããã«ã ReactContext
ãã°ããŒãã«ã«åç
§ããªãããã«ããããšã ãšæããŸãã ããã§åé¡ãçºçããå¯èœæ§ã®ããä»ã®ã°ããŒãã«ããããŸããïŒ
@mridgwayç§ãééã£ãŠããªããã°ãã°ããŒãã«ReactContext
ã¯äºææ§ã®ãããã®ã§ããã0.14ã§ãªããªãã§ãããã ããããç§ã¯ééã£ãŠãããããããŸããã
@gaearonãããããã¯ç§ãwithContextã®éæšå¥šããåŸãæå³ã§ãã
ïŒ+1ïŒãã®ATMã«react-router
ã䜿çšããŸãã @mridgwayã®ã¢ãããŒãã¯éåžžã«åççã«èãããŸãã
ãã®åé¡ã«å¯Ÿããå°ãç°ãªãèŠæ¹ã¯ããã³ãã©ãŒïŒwebpackãªã©ïŒã«ãã£ãŠçæãããã³ãŒããã£ã³ã¯ã®éåæããŒããåŠçããæ¹æ³ã§ãã
ãã®ãã±ããã§èª¬æãããŠããããã«ïŒ https://github.com/rackt/react-router/issues/1402ïŒ ãéåæã¬ã³ããªã³ã°ã®ãµããŒãã«é¢ããåé¡ã¯ãé¢é£ãããã£ã³ã¯ãæåã®ãã£ã³ã¯ã«ãŸã ããŒããããŠããªããããæåã®ã¬ã³ããªã³ã°ãnullã«èŠããããšã§ãã¬ã³ããªã³ã°ãã¹ãçµæãšããŠãDOMã®ã«ãŒãã«<noscript>
ãããã§ãã¯ãµã ã倱æããŸãã ãã®åŸããã«ãã¹ãŠãé©åã«é
眮ãããŸãããããŒã«ã«ã§äœæ¥ããå Žåã¯UIãã¡ãã€ãããã£ãŒã«ãã§äœæ¥ããå Žåã¯ç¹ã«ãããŠã³ããŒããããã£ã³ã¯ãé©åãªãµã€ãºïŒããšãã°ã> 30KBïŒã®å Žåã¯ãã¡ãã€ããçºçããŸãã
倧ããªã¢ããªãè€æ°ã®ãã£ã³ã¯ã«åå²ããæ©èœã¯ç§ãã¡ã«ãšã£ãŠéèŠã§ãããããŒã¿ãã§ããã®åé¡ã解決ããŸããïŒãµãŒããŒã§ã¬ã³ããªã³ã°ããŠããŒã¿ã®äŸåé¢ä¿ããã§ããããåã«ãã©ããŒã¹ã§ããreact-routerãšãã¹ããããã«ãŒãã䜿çšããŸããïŒããã¯æåŸã®ããŒã¹ã§ãããã³ããšã³ãã®Reactãœãªã¥ãŒã·ã§ã³ã«å®å šã«ç§»è¡ããããšã劚ããããºã«ã®äŸã§ãã
@anatomicããã¯Reactã®è²¬ä»»ã§ã¯ãããŸãããé©åã«ãã£ã³ã¯ããå¿ èŠãªãã£ã³ã¯ããã¹ãŠèªã¿èŸŒãŸãããŸã§ã¬ã³ããªã³ã°ã延æããã®ã¯ããªãã®ä»äºã§ãã èšãæãããšãã³ã³ããŒãã³ãã®1ã€ãå€éšã©ã€ãã©ãªã«äŸåããŠããå Žåãããã䜿çšããåã«æºè¶³ãããã®ã¯æããã«åé¡ã§ããReactã¯è©ŠããŠã¿ãŠãå®è¡ã§ããªãã£ããããåãããšãå šé¢çã«åœãŠã¯ãŸããŸãã
<WaitFor for={MyAsyncLoadedCompSignal} until={...} then={() => <MyAsyncLoadedComp ... />} />
ãèªåã«åã£ã代æ¿æŠç¥ãèªç±ã«å®è£
ããŠãã ããã ãããããããã¯æ¬è³ªçã«æèŠãåãããŠãããReactãæäŸãã¹ãããããã¯æäŸããå¿
èŠã®ãããã®ã§ã¯ãªããããã³ãã¥ããã£ã«ä»»ããã®ãæåã§ãã
Reactã³ã³ããŒãã³ãã®ç¯å²å€ã«éåæã®ãã®ãä¿æããããšããå§ãããŸãã次ã«äŸã瀺ããŸãã
import React from 'react';
import Layout from './components/Layout';
import NotFoundPage from './components/NotFoundPage';
import ErrorPage from './components/ErrorPage';
const routes = {
'/': () => new Promise(resolve => {
require(['./components/HomePage'], HomePage => { // Webpack's script loader
resolve(<Layout><HomePage /></Layout>);
});
}),
'/about': () => new Promise(resolve => {
require(['./components/AboutPage'], AboutPage => { // Webpack's script loader
resolve(<Layout><AboutPage /></Layout>);
});
})
};
const container = document.getElementById('app');
async function render() {
try {
const path = window.location.hash.substr(1) || '/';
const route = routes[path];
const component = route ? await route() : <NotFoundPage />;
React.render(component, container);
} catch (err) {
React.render(<ErrorPage error={err} />, container);
}
}
window.addEventListener('hashchange', () => render());
render();
Webpack Code Splitting ã React.js Routing from Scratch and react-routing ïŒè¿æ¥å ¬éïŒãåç §ããŠãã ããã
@syranideãããããäœæ¥ãç¶ããŠãããŸãããäžèšã®ããã«ãã€ããªã§ã¯ãªããšæããŸãã ã«ãŒã¿ãŒã¯Reactç°å¢ã®å€ã«ããã®ã§ã¯ãªãã³ã³ããŒãã³ãã§ãããããreact-routerã䜿çšããŠãããããããã¯ã¹ã«ããã€ãã®åé¡ãçºçããå¯èœæ§ããããŸãã
<WaitFor ... />
ã¢ãããŒããå®è¡ããå Žåã§ããæåã®ã¬ã³ããªã³ã°ã§å¥ã®DOMãååŸãããã³ã³ãã³ãã®ã¡ãã€ããæ¶å€±ãçºçããŸããïŒ
ç§ãã¡ããã£ãå Žå
ã¢ãããŒãã確ãã«æåã®ã¬ã³ããªã³ã°ã§å¥ã®DOMãååŸããŸãããããã§ãã³ã³ãã³ãã®ã¡ãã€ã/æ¶å€±ãçºçããŸããïŒ
ã¡ãã€ããæãŸãªãå ŽåïŒäžéšã®å ŽåïŒãã¬ã³ããªã³ã°ããåã«ãäŸåãããã¹ãŠã®ãã£ã³ã¯ãããŒããããã®ãåŸ
ã€ã ãã§ããwebpackã¯ããã®ããã«äœ¿ããrequire.resolve
ãŸãã
PSã ã¯ããreact-routerããã®ä»ã®äœ¿çšããŠãããã®ã¯ç¢ºãã«è§£æ±ºçãè€éã«ããŸãããããã§ãReactã®è§£æ±ºãã¹ãåé¡ã§ã¯ãããŸããã
ã¡ãã€ããæãŸãªãå ŽåïŒäžéšã®å ŽåïŒãã¬ã³ããªã³ã°ããåã«ãäŸåãããã¹ãŠã®ãã£ã³ã¯ãããŒããããã®ãåŸ ã€ã ãã§ããwebpackã¯ããã®ããã«äœ¿ããrequire.resolveãæäŸããŸãã
ç§ã¯ããã調ã¹ãŸãã require.resolve
ç§ã®ç解ã¯ããããã¢ãžã¥ãŒã«ã®IDã®åæã«ãã¯ã¢ããã§ããããµãŒããŒãžã®ããªãããå«ãŸãªãã£ããšããããšã§ãããïŒ ãã£ã³ã¯ã®èªã¿èŸŒã¿ã管çããããã«require.ensure
ã䜿çšããŠããŸãã
ã³ãŒããããäžåºŠèŠããšãreact-routerã«ãµãŒããŒäžã§ã¬ã³ããªã³ã°ãããŠãããšæãããããæšæºã®ã¯ã©ã€ã¢ã³ãåŽã®ã¢ãããŒãã«åŸãããšã§ãåé¡ãåé¿ã§ãããšæããŸãã
const history = new BrowserHistory();
if (typeof history.setup === "function") {
history.setup();
}
Router.run(routes, history.location, (err, initialState, transition) => {
React.render(<Provider redux={redux}>{() => <Router key="ta-app" history={history} children={routes} />}</Provider>, document.getElementById('ta-app'));
});
ããã調ã¹ãŸããrequire.resolveã«ã€ããŠã®ç§ã®ç解ã¯ããããã¢ãžã¥ãŒã«ã®IDã®åæã«ãã¯ã¢ããã§ããããµãŒããŒãžã®ããªãããå«ãŸãªãã£ããšããããšã§ãããïŒ ãã£ã³ã¯ã®èªã¿èŸŒã¿ã管çããããã«require.ensureã䜿çšããŠããŸãã
ç³ãèš³ãããŸããããã¯ãã require.ensure
ãæå³ããŸããã ã³ãŒã«ããã¯ã¯ããã¹ãŠã®äŸåé¢ä¿ãæºããããå Žåã«ã®ã¿å®è¡ããããããrender / setStateããã®äžã«é
眮ããã ãã§ãã
ããããŸãããããã¯ç§ãã¡ãããããã£ãŠããæ¹æ³ã®ãããªãã®ã§ããããªãã®è¿äºã«æè¬ããŸãã ããã¯react-routerã§å¯ŸåŠããå¿ èŠããããã®ã®ããã«æããã®ã§ãããã§è°è«ãç¶ããŸã-ããããã®äŒè©±ãããã®ã«ééã£ãå Žæã§ãã£ãå Žåã¯ç³ãèš³ãããŸããïŒ
require.ensure
ãé²ãã¹ãéã§ããããšã¯ééããããŸãããç§ãã¡ã®æçµçãªåé¡ã¯ãçŸåšã¢ã¯ã»ã¹ããŠããã«ãŒãã«ãªã³ã¯ããå¿
èŠããããããã«ãŒã¿ãŒã«çŽæ¥æ¥ç¶ãããŠããããšã ãšæããŸãã react-routerã¯ã³ã³ããŒãã³ãããŒã¹ã§ãããã¬ã³ããªã³ã°ããªãŒã«é¢é£ä»ããããŠããŸãã äžèšã®ç§ã®ããã¯ããªããã°ããã¹ãŠãéåæã§ããŒããããåã«ããªãŒã衚瀺ããæ¹æ³ãšæŠãããšã«ãªããŸãïŒãŸãã¯ã«ãŒãã£ã³ã°ããžãã¯ãè€è£œããŠãé¢é£ãããã£ã³ã¯ããããã¬ãã«ã§ããŒãã§ããããã«ããŸãïŒã
require.ensureãé²ãã¹ãéã§ããããšã¯ééããããŸãããç§ãã¡ã®æçµçãªåé¡ã¯ãçŸåšã¢ã¯ã»ã¹ããŠããã«ãŒãã«ãªã³ã¯ããå¿ èŠããããããã«ãŒã¿ãŒã«çŽæ¥æ¥ç¶ãããŠããããšã ãšæããŸãã react-routerã¯ã³ã³ããŒãã³ãããŒã¹ã§ãããã¬ã³ããªã³ã°ããªãŒã«é¢é£ä»ããããŠããŸãã äžèšã®ç§ã®ããã¯ããªããã°ããã¹ãŠãéåæã§ããŒããããåã«ããªãŒã衚瀺ããæ¹æ³ãšæŠãããšã«ãªããŸãïŒãŸãã¯ã«ãŒãã£ã³ã°ããžãã¯ãè€è£œããŠãé¢é£ãããã£ã³ã¯ããããã¬ãã«ã§ããŒãã§ããããã«ããŸãïŒã
ç§ã¯react-routerã«ç²ŸéããŠããŸããããããã§ãsetRoute(...)
=> require.ensure([], function() { require(...); setRoute(...); })
å Žåã§ãããšæ³åããŠããŸãããããã¯å®éã«ã¯å®çšçã§ã¯ãªããããå¥ã®ã¬ãã«ã®éæ¥åç
§ãå°å
¥ããŸãã ã«ãŒãã®ããããšããããã®éåærequire.ensure
ããŒããŒã ãã«ããŒfunction asyncSetRoute(...) { loadRoute(route, function() { setRoute(...); }}
ãäœæããŸãã代ããã«ã asyncSetRoute
ãåŒã³åºããšããã¹ãŠã®æºåãæŽããŸã§ã«ãŒã¿ãŒã®æŽæ°ã延æãããŸãã
æ¬äŒŒã³ãŒããšäžçš®ã®ãžã§ããªãã¯ã§ãããããã¯ç§ã«ãšã£ãŠå šäœçãªã¢ãããŒãã®ããã§ãã ãã¶ãreact-routerããããæäŸããã¯ãã§ãããããã§ã¯ãªããããããŸãã...ãã¶ãããã¯å€éšãã«ããŒãšããŠçæ³çã«æäŸãããŠããã®ãããããŸããããç§ã«ã¯ããããŸããã
ãããã£ãŠãäœæéãã®èª¿æ»ã®çµæããã¹ãŠãäžããäžã«ãã£ãŒãããªãéãããµãŒããŒåŽã®ã¬ã³ããªã³ã°ã_äžå¯èœ_ã§ããããšã確èªããŸããïŒïŒïŒã
èããããçæçãªè§£æ±ºçïŒ
A.ã¹ãã¢ãäºåã«å
¥åãããµãŒããŒåŽã®èªã¿èŸŒã¿ãåæåãã
B. 1ã€ã®ããŒã¿ãªããžã§ã¯ããéåæã§ãã§ããããåŸããã¹ãŠã1ã€ã®ããŒã¿å ¥åãšããŠäžãããã£ãŒãããŸãã
reïŒ 'A'ã ã¬ã³ããªã³ã°æ§é ãã©ã®ããã«ãªããããã§ã«ç¥ã£ãŠããªãéããããã¯æ©èœããŸããã ããŸããŸãªã³ã¬ã¯ã·ã§ã³/ã¢ãã«/ APIã®äŸåé¢ä¿ãç¥ãããã«ããããã¬ã³ããªã³ã°ããå¿ èŠããããŸãã ãŸãã2ã€ã®ç°ãªãAPIã䜿çšããã«ãã¯ã©ã€ã¢ã³ãã§ãã§ãããéåæã«ãããµãŒããŒã§åæãããã«ã¯ã©ãããã°ããã§ããïŒ
reïŒ 'B'ã åºæ¬çã«äžèšãšåãåé¡ã§ãã 人ã ã¯ãããããã®ã«ãŒãã«å¯Ÿå¿ããããã«ãäŸåé¢ä¿ã®ããJSONãã»ãšãã©äœæããå¿ èŠããããŸãããïŒ
ReactããµããŒããããœãªã¥ãŒã·ã§ã³ãåŸ ã€éãä»ã«çæçãªãœãªã¥ãŒã·ã§ã³ã¯ãããŸããïŒ ãŠãŒã¶ãŒã©ã³ããã©ãŒã¯ãŸãã¯ãã©ã°ã€ã³ã¯ãããŸããïŒ https://www.npmjs.com/package/react-async ïŒ
@NickStefan
åé¡ãããããŸããã :-(
fetchData
ãããªéçã¡ãœãããå®çŸ©ããŸããfetchData
ãååŸããã³ã³ããŒãã³ããå®äºããã®ãåŸ
ã£ãŠããã¬ã³ããªã³ã°ããŸãã ããã«ãããFluxãŸãã¯Reduxã¹ãã¢ã€ã³ã¹ã¿ã³ã¹ãäºåã«å
¥åãããŸãã ã¹ãã¢ã€ã³ã¹ã¿ã³ã¹ã¯ã·ã³ã°ã«ãã³ã§ã¯ãªãããšã«æ³šæããŠãã ãããç¹å®ã®ãªã¯ãšã¹ãã«ãã€ã³ããããŠããããããªã¯ãšã¹ãã¯åé¢ããããŸãŸã§ãããã®ã¢ãããŒãã説æããReduxã®åªãããã¥ãŒããªã¢ã«ã¯æ¬¡ã®ãšããã§ãïŒ https ïŒ//medium.com/@bananaoomarang/handcrafting -an-isomorphic-redux-application-with-love-40ada4468af4
@gaearonãè¿·æããããã
ããã¯è¯ããã©ãã¯ã¹ã®ç¿æ £ã§ãããããã¯æœåšçã«å¶éãããŠããŸãããïŒ ãã¥ãŒããªãŒã®äžéšã«ãéåžžã«ç°ãªãããŒã¿ãå¿ èŠãšããå°ããªã³ã³ããŒãã³ããè¿œå ããå Žåã¯ãã«ãŒãã§ããŒã¿ã®äŸåé¢ä¿ãç·šéããå¿ èŠããããŸãã
ç§ãæ±ããŠããã®ã¯ãæ·±ããã¹ããããã³ã³ããŒãã³ããéåæããŒã¿ã®ããŒãºãå®çŸ©ããæ¹æ³ã§ãã
ã«ãŒãã³ã³ããŒãã³ãã«ããŒãºãè¿œå ããå¿ èŠãããå Žåãã«ãŒãããã®1ã€ã®ãµãã³ã³ããŒãã³ãã®ããŒãºã«çµåããŠããŸãããïŒ
@NickStefanãšreact-routing ãããšãã°ãéåæããŒã¿ã®ãã§ããã¯æ¬¡ã®ããã«ãªããŸãã
import Router from 'react-routing/lib/Router';
import http from './core/http';
const router = new Router(on => {
on('/products', async () => <ProductList />);
on('/products/:id', async (state) => {
const data = await http.get(`/api/products/${state.params.id`);
return data && <Product {...data} />;
});
});
await router.dispatch('/products/123', component => React.render(component, document.body));
ãããã®ãœãªã¥ãŒã·ã§ã³ã¯æ©èœããŸããããã¹ãŠã®ããŒã¿ã®ããªãã§ãããã«ãŒã¿ãŒã«ãã€ã³ããããŠããããã§ãã ããã¯ã»ãšãã©ã®å Žååé¡ã§ã¯ãããŸãããïŒURLã¯ããŒãžã«äœã衚瀺ãããããããã£ãŠã©ã®ããŒã¿ãå¿ èŠããå®çŸ©ããŸãïŒãäžè¬çã«ã¯å¶éã§ãã ãã¹ãŠãåç¬ã§åŠçããã¹ã¿ã³ãã¢ãã³ã®åå©çšå¯èœãªã³ã³ããŒãã³ãïŒTwitterã¹ããªãŒã ãã³ã¡ã³ããã«ã¬ã³ããŒãªã©ïŒãäœæããããšã¯ã§ãããã³ã³ããŒãã³ãéå±€ã«æ¿å ¥ããã ãã§æžã¿ãŸãã ãããå¯èœã«ããå¯äžã®æ¹æ³ã¯react-asyncã§ãããããã¯ã»ãšãã©ããã¯ã§ãã
Reactã³ã³ããŒãã³ãã¯ããã®ããã«äœ¿çšããããšãæå³ãããã®ã§ã¯ãªãã_controller_-viewsãããå€ãã®ãã¥ãŒã§ãããšæããŸãã ãããããå®å šã«æ°ããã©ã€ãã©ãªãReactã®åºç€ã®äžã«åºçŸããå¿ èŠããããŸãã
ç§ã®å€¢ã¯ããã€ã®æ¥ããWordpressãDrupalãModxãªã©ã®Reactã䜿çšããŠå®å šãªCMSãäœæã§ããããã«ãªãããšã§ãã ãã ããHTML / PHPã¹ããããã®ä»£ããã«ãReactã³ã³ããŒãã³ãããWebãµã€ããæ§æããŸãã
@NickStefan
ããªãã®ãªã¹ãããããµãŒããŒã®ããŒã¿äŸåæ§ã®è§£æ±ºçã¯ãã«ãŒãã³ã³ããŒãã³ãïŒéçã¡ãœãã/ãªã³ã¯ããèšäºïŒã§ã®ã¿ããŒã¿ã®ããŒãºãå®çŸ©ããããšã§ãããšç§ã¯æ£ãããšæããŸãã ããŒã¿ã®äŸåé¢ä¿ãã«ãŒãã§å®çŸ©ãããŠããå Žåã¯ãã¹ãã¢ãªã©ãäºåã«å ¥åããæ¹ãã¯ããã«ç°¡åã§ãã
ã«ãŒãã³ã³ããŒãã³ãã«ããŒãºãè¿œå ããå¿ èŠãããå Žåãã«ãŒãããã®1ã€ã®ãµãã³ã³ããŒãã³ãã®ããŒãºã«çµåããŠããŸãããïŒ
ã«ãŒãã§ã¯ãªããã«ãŒããã³ãã©ãŒã¬ãã«ã§ã ã¢ããªã«ã¯å€ãã®ã«ãŒããã³ãã©ãŒãå«ãŸããŠããå¯èœæ§ããããŸãã ããã«ã React Routerã®ãããªã©ã€ãã©ãªã¯ããã¹ããããã«ãŒããã³ãã©ãŒããµããŒããé
åãå«ãŸãããããããããPromise.all
ã§ããŸãã ããã¯æå³ããããŸããïŒ
ããã¹ãŠã®ã³ã³ããŒãã³ããäŸåé¢ä¿ã宣èšã§ãããã»ã©ãã现ããã¯ãããŸããããã»ãšãã©ã®å ŽåãããŒã¿ãã§ãããã«ãŒããã³ãã©ãŒïŒæäžäœããã³ãã¹ãããããã³ãã©ãŒïŒã«å¶éããã ãã§ååã§ããããšãããããŸããã 以äžã«ã props
ãä»ããŠããŒã¿ãåãå
¥ããçŽç²ãªã³ã³ããŒãã³ãããããããããŒã¿ããã§ãããããŠããããšã_èªè_ããŠããŸããã 圌ãããããèŠæ±ã§ããªãããšã¯çã«ããªã£ãŠããŸãã
ããã¹ãŠã®ã³ã³ããŒãã³ããäŸåé¢ä¿ã宣èšã§ãããã¢ãããŒãã¯ãããçš®ã®èŠæ±ãããåŠçãœãªã¥ãŒã·ã§ã³ããªãéããå®çšçã§ã¯ãããŸããã <User>
ãAPIåŒã³åºããå¿
èŠã§ãããšå®£èšãã100åã®<User>
ã®ãªã¹ããã¬ã³ããªã³ã°ãããšããŸãã100åã®ãªã¯ãšã¹ããåŸ
ã¡ãŸããïŒ ãã®çš®ã®ããŒã¿ãã§ããèŠä»¶ã®ç²åºŠã¯ããªã¯ãšã¹ãããããœãªã¥ãŒã·ã§ã³ãããå Žåã«ã®ã¿æ©èœããŸãã ãããããªãã«åã£ãŠãããªãããªã¬ãŒã¯ãŸãã«ããã§ãã ãã ãããã®ããã®ç¹å¥ãªããã¯ãšã³ããå¿
èŠã«ãªããŸãã
@NickStefançŸåšãã³ã³ããŒãã³ãããšã®éåæãã§ããã¯ãµããŒããããŠããŸãããè¿œå ãããã®ã§ããããã®åé¡ã¯ç§ãã¡ã®é²æç¶æ³ã远跡ããŸããã誰ãç©æ¥µçã«åãçµãã§ãããã倧èŠæš¡ãªãªã¹ãã©ãå¿ èŠã«ãªãããããã°ããæéãããããŸãã
@gaearon
ããã¹ãŠã®ã³ã³ããŒãã³ããäŸåé¢ä¿ã宣èšã§ãããã¢ãããŒãã¯ãããçš®ã®èŠæ±ãããåŠçãœãªã¥ãŒã·ã§ã³ããªãéããå®çšçã§ã¯ãããŸããã
ããã«ã€ããŠããå°ãèããåŸãç§ã¯ããªãã«åæããŸãã ç§ãæ¢ããŠãããã®ã¯å®éã«ã¯å®çšçã§ã¯ãããŸããã
ç§ã¯ããšããšããªãã®100人ã§ãã<UsersContainer>
ãäœæããã ãã§ãïŒã ããããããã¯åã«æ
£ç¿ãæã£ãŠããã ãã®ã人ã«ã¹ã±ãŒã©ãã«ãã§ã¯ãããŸããã ã«ãŒããŸãã¯ã«ãŒã¿ãŒãžã®ãã¹ãŠã®äŸåé¢ä¿ã匷å¶ããã®ãããããæåã§ãã ãªã¬ãŒã®ãããªãã®ã§ããã3ã€ã®ç°ãªãã³ã³ããïŒRelayContainerãRelayRootContainerãRelayRouterãªã©ïŒã䜿çšããŠã«ãŒãã§äŸåé¢ä¿ã宣èšããããã«åŒ·å¶ããŸãã ããã¯ãäŸåé¢ä¿ã®å®£èšãããªãŒã®äžäœã«æ¬è³ªçã«ãæã¡äžãããããšãå¯äžã®æ¹æ³ã§ãããšããç¹ã蚌æããŠããŸãã
ããïŒ
ããã«é¢ããæŽæ°ã¯ãããŸããïŒ
+1
ããªããæ¬åœã«ããã«ã€ããŠèãããªãã°ãããªãã¯ãããããããªããšç§ã¯äž»åŒµããŸãã ç§ã¯åœåãReactã«éåæã¬ã³ããªã³ã°ãå®è¡ãããããšæã£ãŠããŸããã ãããããã®ã¹ã¬ããã®ä»ã®äººãã¡ã¯ãããã§ãªããã°ç§ãçŽåŸãããŸããã
ãªã¬ãŒã§ããåºæ¬çã«ã¯ãã«ãŒãã³ã³ãã宣èšããªã¬ãŒã³ã³ãããªã©ã䜿çšããŠãäŸåé¢ä¿ãããªãŒã®äžäœã«ãåŒãäžãããå¿ èŠããããŸããåæã¬ã³ããªã³ã°ããã®æ¹æ³ã§ãã
éåæã¬ã³ããªã³ã°ã¯æªå€¢ã«ãªãå¯èœæ§ããããŸãã ç§ã¯ããªã¯ãšã¹ãã¢ãã¡ãŒã·ã§ã³ãã¬ãŒã ã§åã ã®æŽæ°ãè¡ãããã«ãããã³ã°ãããããã¯ããŒã³ãæã€äŒç€Ÿã®ã³ãŒãããŒã¹ã§ã®äœæ¥ã®çµéšãã話ããŸãã
åæããŸããã 以åã¯ãããå¿ èŠã ãšæã£ãŠããŸããããå®éã«ã¯ãããŒãããããŒã¿ããã¥ãŒã§æå®ããã®ã¯éã§ãã ãã¥ãŒã¯ã¢ããªã±ãŒã·ã§ã³ã®ç¶æ ã®é¢æ°ã§ãããããèªäœããªã¯ãšã¹ãã®é¢æ°ã§ãïŒã»ãã·ã§ã³ãããå Žåã¯ãŠãŒã¶ãŒã®ç¶æ ã®å ŽåããããŸãïŒã ãããReactã®ãã¹ãŠã§ãã ã³ã³ããŒãã³ããããŒãããããŒã¿ãæå®ã§ããããã«ããããšã¯ããäžæ¹åã®ããŒã¿ãããŒãã®èãæ¹ã§ããIMOã«åããŸãã
ããŒãããããŒã¿ããã¥ãŒã§æå®ããã®ã¯ãå®éã«ã¯éæ¹åã§ãã
ãããæ¬åœãã©ããã¯å®å šã«ã¯ããããŸããã å Žåã«ãã£ãŠã¯ãããŒãããããŒã¿ãç¥ã£ãŠããã®ã¯ã³ã³ããŒãã³ãã ãã§ãã ããšãã°ããŠãŒã¶ãŒãããŒãã®å€§èŠæš¡ãªã°ã©ããåç §ã§ããæ¡åŒµå¯èœãªããªãŒãã¥ãŒããããšããŸããã©ã®ããŒã¿ãããŒãããå¿ èŠãããããäºåã«ç¥ãããšã¯äžå¯èœã§ãã ã³ã³ããŒãã³ãã ãããããç解ã§ããŸãã
ãšã«ãããããªããžãä»ããŠéä¿¡ããããã«éåæãå¿ èŠãªWebã¯ãŒã«ãŒïŒïŒ3092ïŒå ã§Reactã³ãŒããå®è¡ãããšããã¢ã€ãã¢ãè¿œæ±ããå Žåããã®è°è«ã¯ã¯ããã«é¢é£æ§ãé«ããªãå¯èœæ§ããããŸãã
倧ããªããªãŒãã¥ãŒã®äŸã§ããµãŒããŒåŽã§ãã§ã«éããŠãããã¹ã䜿çšããŠã¬ã³ããªã³ã°ã§ããããã«ãããå Žåã¯ããã®ãã¹ãURLæ§é ã«è¿œå ããŸãã ãã®ãããªè€éãªã³ã³ããŒãã³ããããã€ãããå Žåã¯ããããã®ç¶æ ãGETãã©ã¡ãŒã¿ãŒã§è¡šããŸãã ãã®ããã«ããŠããããã®ã³ã³ããŒãã³ãã¯SSRã®ãã¹ãŠã®å©ç¹ã享åã§ããŸããã€ãŸããã¯ããŒã«å¯èœã§ãå±¥æŽã䜿çšããŠããã²ãŒãã§ãããŠãŒã¶ãŒã¯ã³ã³ããŒãã³ãå ã®ããŒããžã®ãªã³ã¯ãå ±æã§ããŸããããã§ããµãŒããŒãå¿ èŠãªããŒã¿ãå€æããæ¹æ³ããããŸããå¿çãã¬ã³ããªã³ã°ããããã«ãã§ãããããŸãã
ã°ã©ããããªãŒãšééããŠæŽæ°ããŸããããããã§ãããã®ã°ã©ãã«å¯ŸãããŠãŒã¶ãŒã®ãã¥ãŒã®ç¶æ ã¯URLæ§é ã§è¡šãå¿ èŠããããšæããŠããŸãã ãŸããããªããå®éã«Reactã«åãçµãã§ããããšã«æ°ã¥ããŠããŸããã§ããã ããŒã¿ã¬ã€ã€ãŒããã¥ãŒãšå圢ã«çµ±åããããã®ãã¬ãŒã ã¯ãŒã¯ã«åãçµãã§ããå Žåãããã¯çŽ æŽãããããšã§ãã ããããããã¯ãã¥ãŒã®é åãè¶ ããŠãããReactããã«ã¹ã¿ãã¯ã³ã³ãããŒã©ãŒã®åœ¹å²ãæ ãã¹ãã§ã¯ãªãããšã«åæã§ãããšæããŸãã
ã¹ã¬ããå šäœãèªãã§ããªãã®ã§ãããããã§ã«è°è«ãããŠããå Žåã¯ç³ãèš³ãããŸããã
æ¬åœã«åœ¹ç«ã€ããšã®1ã€ã¯ãã³ã³ããŒãã³ãããéå§/ã€ã³ã¹ã¿ã³ã¹åãããŠã©ã€ããµã€ã¯ã«ã¡ãœãããèµ·åããreact-dom/server
ã¡ãœããããããéçºè
ãã³ã³ããŒãã³ããhtmlæååã«ã¬ã³ããªã³ã°ããæºåãã§ãããšãã«æ±ºå®ã§ããããã«ããããšã§ãã ã ããšãã°ãéçºè
ã¯setTimeoutãŸãã¯ããä¿¡é Œæ§ã®é«ããã®ã䜿çšããŠãéåæã¡ãœãããå®äºããã®ãåŸ
ã€ããšãã§ããŸãã
ããã¯ããããéæããããã«çŸåšreduxã§äœ¿çšããŠãããããã¯ãã§ãã
// start/instantiate component
// fires componentWillMount methods which fetch async data
ReactDOM.renderToString(rootEle)
// all my async methods increment a `wait` counter
// and decrement it when they resolve
const unsubscribe = store.subscribe(() => {
const state = store.getState()
// as a result, when there are no more pending promises, the wait counter is 0
if (state.wait === 0) {
unsubscribe()
// all the data is now in our redux store
// so we can render the element synchronously
const html = ReactDOM.renderToString(rootEle)
res.send(html)
}
})
ãã®ã¢ãããŒãã®åé¡ã¯ã2çªç®ã®ReactDOM.renderToString
ããã¹ãŠã®componentWillMount
ã¡ãœãããå床起åããäžèŠãªããŒã¿ãã§ãããçºçããããšã§ãã
ããã¿ããªïŒ ããã¯çŸåšåãçµãã§ãããã®ã§ããïŒ ãã®åé¡ã¯ãŸããŸãéèŠã«ãªã£ãŠãããšæããŸãã ç§ã¯æè¿ãreact reduxã®connect
ãdataConnect
ã«æ¡åŒµããã©ã€ãã©ãªãäœæããŸããããã®ã©ã€ãã©ãªã§ã¯ãã³ã³ããããŒã¿ã®èŠä»¶ãæå®ã§ããŸãã ãããã®ããŒã¿èŠä»¶ã¯ãã©ã³ã¿ã€ã ã«ãã³ãã«ãããåäžã®ãªã¯ãšã¹ãã§GraphQLã䜿çšããŠã¯ãšãªãããŸãã ããã¯ãæ§æå¯èœæ§ãšåé¢ãä¿é²ããããããã©ãŒãã³ã¹ã®é«ããã§ãããä¿èšŒãããããããŒã¿ä»æ§ã®å°æ¥ã§ãããšæããŸãã ïŒãªã¬ãŒã§èŠããããã¹ãŠã®æŠå¿µïŒ
äžèšã®åé¡ã¯ãµãŒããŒåŽã®ã¬ã³ããªã³ã°ã§ãã æçµçã«ã©ã®ããŒã¿èŠä»¶ã«ãªãããéçã«åæã§ããªããããçŸåšããã³ãã«ãDBããã¯ãšãªããããã«äžåºŠã¬ã³ããªã³ã°ããreduxã¹ãã¢ãé衚瀺ã«ããŠãããåã¬ã³ããªã³ã°ããŠæçµçãªæååãååŸããå¿ èŠããããŸãã ã ãã®åé¡ã¯@olalondeã®åé¡ãšäŒŒãŠããŸãã
åå¿èŠçŽ ããªãŒãžã®ã¢ã¯ã·ã§ã³ãšæŽæ°ãããªã¬ãŒãããªã³ããã³ãã§DOMæååã®çµæãååŸã§ããã®ã¯çŽ æŽãããããšã§ãã ãããç§ããããæãæ¹æ³ã§ãïŒ
const virtualTree = ReactDOM.renderVirtual(rootEle);
// get the bundled query from redux store for example
const bundle = store.getState().bundle;
// Fetch the data according to the bundle
const data = fetchDataSomehow(bundle);
// hydrate store
store.dispatch({type: 'hydrate', data});
// components that should update should be marked on the virtual tree as 'dirty'
virtualTree.update(); // this would only update the components that needed update
const domString = virtualTree.renderToString(); // final result
ä»ã®ãªãã·ã§ã³ã¯ããã¹ãŠã®ããã¯ãååšããdidMountã®ããã«æ©èœããŠããç¶æ ã§ãã¯ã©ã€ã¢ã³ãåŽã®ããã«èªç±ã«æŽæ°ã§ããããã«ããããšã§ãã ãã ããDOMãå€æŽãã代ããã«ãä»®æ³DOMè¡šçŸãå€æŽãããªã³ããã³ãã§æååã«ã¬ã³ããªã³ã°ããŸãã
çããã¯ã©ãæããŸããïŒ èæ ®ãã¹ãããšããããŸããããããšãå®å šã«ééã£ãŠãããšæããŸããïŒ
ããã«ã¡ã¯ãã¿ããªã ç§ã¯ãã®å·ã1幎ã»ã©è³ŒèªããŠããŸãã åœæãã³ã³ããŒãã³ãã¯ã¢ãžã¥ãŒã«æ§ã®äž»èŠãªåäœã§ãã£ããããã³ã³ããŒãã³ãå ããããŒãããå¿ èŠã®ããããŒã¿ãæå®ã§ããå¿ èŠããããšèããŠããŸããã ãã®åé¡ã¯ç§ã«ãšã£ãŠéåžžã«éèŠã§ãããReactã®æ¬¡ã®ããŒãžã§ã³ã§ç¢ºå®ã«è§£æ±ºããããšæããŸããã
ãã以æ¥ãREST / HATEOSã®èåŸã«ããçæ³ãããæ·±ãå°éããããã«ãªããŸãããããã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã·ã¹ãã ïŒãã©ãŠã¶ãŒãã¯ããŒã©ãŒãã¢ããªã±ãŒã·ã§ã³ãµãŒããŒããããã·ãCDNãªã©ïŒã®æéãšãªãååãç¶ããŠã ãã®åé¡ã«é¢é£ããŠããããã_URLã¯ã¢ããªã±ãŒã·ã§ã³ã®ç¶æ ãçã«è¡šããã®ã§ããå¿ èŠããããŸã_ã ããã ãã§ããªã¯ãšã¹ããåŠçããããã«å¿ èŠãªæ å ±ã決å®ããå¿ èŠããããŸãã ãã¥ãŒã¬ã€ã€ãŒã®Reactãããã決å®ããã¹ãã§ã¯ãããŸããã ããŒã¿ã«åºã¥ããŠæ§ç¯ããå¿ èŠããããŸãã ãã¥ãŒã¯ããŒã¿ã®é¢æ°ã§ãããããŒã¿ã¯URLã®é¢æ°ã§ãã
ããã¯ããã¢ã€ãã¢ã ãšèãç¶ããŠããã®ã§ãéå»ã«ãããæšãŠãããšããããã£ãŠããŸããããçŸå®ã®äžçã¯è€éãããŠãããæ©èœãããããšãã§ããŸããã ãããŠæã ãç§ãäžæ©åŸéããäŸãèããŠãç§ãããŸãã«ãè¡åŠè ã§ããã®ãããããšãçæ³äž»çŸ©çã§ããã®ãçåã«æããŸãã ãããããããã®äŸãçèãããšãå¿ ç¶çã«ãURLã§ã¢ããªã±ãŒã·ã§ã³ã®ç¶æ ãè¡šãåççãªæ¹æ³ãèŠã€ããããšãã§ããŸãã
ä»ã®æ¹æ³ã§ã¯åŸãããªãã£ãããã®ãã¹ãŠã®äœæ¥ã§äœãåŸãããŸããïŒ
next
ãªã³ã¯ã FBã°ã©ãAPIã¯ãã®è¯ãäŸã§ããapp.get("*", theOneTrueClientonaserverEntryPoint)
ãšããŠç
§åãã代ããã«ããµãŒããŒã¢ããªã±ãŒã·ã§ã³ãã¬ãŒã ã¯ãŒã¯ãæå³ãããšããã«äœ¿çšã§ããŸãã 200 OK\n\n{status: "error"}
代ããã«ããªã¯ãšã¹ãããæ£ããHTTPã¹ããŒã¿ã¹ã³ãŒããè¿ãããšãã§ããŸãã ã¹ã¿ãŒã«ãŒãã¯é
åçã§ãããããã¯çæ°ã«ã€ãªãããŸããã§ã¯ãã¹ã¿ãŒããŒã«ã§ããReactãæäœãå¶åŸ¡ããŠããªãã®ã§ãããŒã¿ãååŸããã«ã¯ã©ãããã°ããã§ããããã ã¬ã³ããªã³ã°ããã³ã³ããŒãã³ããã©ã®ããã«ç¥ãããšãã§ããŸããïŒ
ç§ã¯ãããèããããã€ããã¯ãããŸãããããã®åé¡ã®ãªã¯ãšã¹ãã®ã³ã¢ããŒãã¯èª€ã£ãæ¹åã«é²ãã§ãããå°ãªããšãããã§èŠãçç±ã®ããã«ãReactã¯ããã«å¯Ÿå¿ããããã«äœãå®è£ ãã¹ãã§ã¯ãªããšåŒ·ãæããŠããŸãæšå¹Žã åªããã¢ããªã±ãŒã·ã§ã³ã¢ãŒããã¯ãã£ã®ããã€ãã®åŽé¢ã¯æããã§ã¯ãªããWebãæ£ããç解ããã®ã¯ç¹ã«å°é£ã§ãã å¿«é©ãã®ããã«åªé ããç ç²ã«ããã®ã§ã¯ãªããã€ã³ã¿ãŒããããšWebãæ§ç¯ããå ç¥ã®ç¥æµããåŠã³ãå°éããå¿ èŠããããŸãã
ãããReactãçŽ æŽããããã®ã«ããŠããã®ã§ããããããã¥ãŒã§ãã æé«ã®çºãã ãã¥ãŒã®ã¿ã λ
@ d4goxnã«åæããªãå¿ èŠããããŸãã ç§ã¯Reactããã¥ãŒã¬ã€ã€ãŒä»¥äžã®ãã®ã«ããããšã¯ããŠããŸãããã«ãŒãã£ã³ã°ã¯éèŠã§ããããã¹ãŠã®ããŒã¿èŠä»¶ãæå®ããã«ã¯ééããªãååã§ã¯ãããŸããã ã³ã³ããŒãã³ã/ã³ã³ãããŒã¬ãã«ã§ããŒã¿èŠä»¶ãæå®ããããšã«ãããReactããã¥ãŒã¬ã€ã€ãŒä»¥äžã®ãã®ã«ããããšã¯ãããŸããã ããã«ãããã¢ããªã®åé¢ãšã¯ãŒã¯ãããŒãå€§å¹ ã«åäžããŸãã ããã¯ãäœæ¥ãåçŽåããã ãã§ãªãã倧ããªã¢ããªã±ãŒã·ã§ã³ãå¿ èŠã«ãªãããšã§ããããŸãã ã¢ããªã«30ã®ã«ãŒãããããããããã«ãŠãŒã¶ãŒãããã¡ã€ã«ã³ã³ããŒãã³ããè¿œå ããããšããŸãã ããããã«ãã¹ãŠã®ããŒã¿èŠä»¶ãæå®ãããŠãã代æ¿ã«ãŒãã«åŸã£ãŠããã®ããŒã¿äŸåé¢ä¿ãè¿œå ããããã«30ã®ã«ãŒããééããå¿ èŠããããŸãã ãã®ã³ã³ããŒãã³ãã®ã³ã³ããã§ããŒã¿ããŒãºãæå®ããå Žåã¯ãå¿ èŠãªå Žæã«ã³ã³ããŒãã³ããè¿œå ããã ãã§ãã ãã©ã°ã¢ã³ããã¬ã€ã§ãã ããã ãã§ãªãããã¹ãŠã®ã³ã³ããŒãã³ãã®ããŒã¿äŸåé¢ä¿ã®ã¯ãšãªãæé©åã§ããŸãã ãªã¬ãŒã¯ããã®è¯ãäŸã§ãããããã«ã€ããŠã®è©±ã¯ç§ããããããã¯ããã«ãã説æããŠããŸãã
ç§ã¯å€ãç¥æµããšãŠãå°æ¬ããŠããŸããããããé²åãšæ°ããæšæºã®äœæã®éçã§ã¯ãªãã¯ãã§ããå°ãªããšãããã¯ç§ãèŠãŠããæ¹æ³ã§ãã
ç§ã®ææ¡ã¯ãåºæ¬çã«Reactãå€æŽããªãããšã§ãããdom / componentsããªãŒãå€æŽãããä»®æ³ã®ã¿ãã®æ¹æ³ãåºæ¬çã«ã¯ãµãŒããŒåŽã§ãå®è¡ãã§ããReactã䜿çšããããšã§ããããã¯ãéåžžã«ç°¡åã«å®è¡ã§ãããšæããŸãïŒã¢ã¯ã·ã§ã³ããããã¯ããã ãã§ãïŒã DOMãå€æŽããŸãïŒã ãã£ãã·ã¥ã䜿çšããŠãCDNãé 眮ããããšãã§ããŸãã ä»æ¥ã®ãµã€ããšã¢ããªã±ãŒã·ã§ã³ã®ãã€ããã¯ã¹ã®æé·ã«äŒŽããéçãã£ãã·ã³ã°ã¯æžå°ããåŸåããããŸãããããã¯å¥ã®ãããã¯ã§ãð
ãã¥ãŒãããŒã¿ãžã®äŸåé¢ä¿ãæå®ããŠããå Žåã¯ãäŸåé¢ä¿ã°ã©ããæé©åãããããæå°éã®ã¯ãšãªæ°ã«å€æããäœããã®æ¹æ³ãå¿ èŠã«ãªããŸãã ãã¥ãŒãäœæããåã«ããŒã¿ãæºåããããšã¯ã§ããŸããããããŒã¿ã2ã€ã®ãã§ãŒãºã«åå²ããããšã¯ã§ããŸããããã¯ããã®ã¹ã¬ããã§ã®èšç»ãç解ããŠããŸãã ããšãã°ããããããç¬èªã®ã¯ãšãªãæã€ãé©åºŠã«è€éãªã³ã³ããŒãã³ãã®ã³ã¬ã¯ã·ã§ã³ãåãäžããŸãã ããããããããã¯ãã¹ãŠåãã³ã³ããŒãã³ãã®ã€ã³ã¹ã¿ã³ã¹ã§ã¯ãªããåäžã®ã¯ãšãªã«æããããããšãã§ãããã¿ãŒã³ã¯ãããŸããã ãããGraphQLãåãçµãã§ããããšã ãšæããŸãã ããŒã¿ã¹ãã¢ããšã«GQLãµãŒããŒãå®è£ ãŸãã¯çµ±åããå¿ èŠããããŸãã æé©åãããGQLã¯ãšãªã®ã©ã®éšåãã©ã®ããŒã¿ã¹ãã¢ã§åŠçããå¿ èŠãããããåé¡ããããšã¯ããªãè€éã«èãããŸãããç§ã®ææ¡ã«ããã®è€éãã®äžéšããããŸãã
ãã®äŸã§ã¯ããã¹ãŠåãããŒã¿ãå¿ èŠãšããã«ãŒããå€æ°ããå Žåããã®ããŒã¿ãœãŒã¹ã®èå¥åãURLããé€å€ããçç±ãšããŠå®éã«ã¯ããããŸããã ã¹ã¿ãã¯ã®ã«ãŒãã®ããªãè¿ãã«å°ããªããŒã¿ãã§ããããã«ãŠã§ã¢ã¢ãžã¥ãŒã«ãããŠã³ãããŸããããã«ããããã®ãŠãŒã¶ãŒãªããžã§ã¯ããã³ã³ããã¹ãã«ã¢ã¿ããããããšã³ãã«ãŒããã³ãã©ãŒã«åããéäžã§ãã³ã³ããã¹ããããå€ãã®ããã«ãŠã§ã¢ã«æž¡ãããŸãã ã«ãŒãReactã³ã³ããŒãã³ãã¯ãã³ã³ããã¹ãã®ãã®ç¹å®ã®éšåãæ°ã«ããªããããããŸãããããããæ°ã«ããå¯èœæ§ã®ãã次ã®ã¬ãã«ã®åäŸããŸãã¯èªåã®åå«ãæ°ã«ããåäŸã«ãããæž¡ããŸãã ãããäžåœã«è€éãŸãã¯æ·±ãé ç·ãå°å ¥ããå Žåã¯ãFluxã¹ãã¢ã®ãããªãã®ãå¿ èŠã«ãªãå¯èœæ§ããããŸãããããèªäœã倧ããªãããã¯ã§ãã
åé¢ãšåé¢ïŒç§ã¯ããã«ããªãã®çã¿ãæããŸãã ç§ã®ææ¡ã§ã¯ã2ã€ã®éåžžã«ç°ãªãã·ã¹ãã ããããããŒã¿ãä¿åãšååŸçšã«æé©åããããã©ãŒã ãããæœè±¡çãªåçŽãã®ããã«æé©åããããã©ãŒã ã«å€æããŸãã ããããç§ã®èŠè§£ã¯ããããã³ã³ããŒãã³ãéå±€ãäžã£ãŠæž¡ãããã®ã§ãããã«é©ãã圢ã«ãããå€æããŠããŸãã äž¡æ¹ã®ã·ã¹ãã ã«è¿œå ããå¿ èŠãããæ©èœãè¿œå ããªãããããã2ã€ã®ã·ã¹ãã ãç·©ãçµåããŠããããšã¯ãç§ãé£ãããšèšãããšã§ã¯ãããŸããããæµæãæå°ã®ãã¹ã§ããããŸããã ããŒã¿ã¹ãã¢ã®ããã°ã©ãã³ã°ãšåçUIã®ããã°ã©ãã³ã°ã®éã®ç²Ÿç¥çãªåãæ¿ãã¯çŸå®çã§ãã 以åã¯ããã¯ãšã³ããšããã³ããšã³ãã®éçºè ãå¥ã ã§ããããHTTPã¯ããã2ã€ã®ãã©ãã€ã éã®ã€ã³ã¿ãŒãã§ãŒã¹ãšããŠæ©èœããŠããŸããã ä»ãç§ã¯ããã1ã€ã®ã¢ããªã±ãŒã·ã§ã³ã«å éšåããããšããŠããŸãããããªãã¯ãããå§ä»»ããããšããŠããŸãã
ã¢ããªã±ãŒã·ã§ã³å ã®è€éããšã¢ã¯ãã£ããã£ã®å¢å ã«ããããµãŒããŒäžã®ã¯ããã«å€§ããªããŒã¿ã»ãããåç §ããéåžžã«å°ããªãªããžã§ã¯ãã§ã¯ã©ã€ã¢ã³ãã®ç¶æ ãè¡šãããšãã§ããªããªããšã¯æããŸããã 倧èŠæš¡ãªãã«ããã¬ã€ã€ãŒã®äžäººç§°ã·ã¥ãŒãã£ã³ã°ã²ãŒã ãèããŠã¿ãŸããããå€ãã®ããšãéãèµ·ãã£ãŠãããã¯ã©ã€ã¢ã³ãããã²ãŒã ã®ãã¹ã/ãµãŒããŒã«å¿ èŠãªæå°éã®æ å ±ãéä¿¡ããããšèããŠããŸãã ããªãã¯ãããã©ããããå°ããããããšãã§ããŸããïŒ ãã¹ãŠã®å ¥åç¶æ ã®ãããã ã¿ã€ã ã¹ã¿ã³ã+äžç¢ºå®æ§ã®ç¯å²ãããŒããŒãçšã®çŽ110ããããã£ãŒã«ããããã³ããŠã¹/ãžã§ã€ã¹ãã£ãã¯ãšVRãããã»ããã®åãçšã®æ°åãã€ãã ã¯ã©ã€ã¢ã³ãã¯äºæž¬ã楜芳çãªã¬ã³ããªã³ã°ãç©çåãè¡ãããµãŒããŒã¯ã¯ã©ã€ã¢ã³ãã®å°ããªç¶æ ãšç¶æ å±¥æŽãã倧éã®æ å ±ãååŸããããªã倧éã®ããŒã¿ãè¿ãããã¹ãŠã®ã¯ã©ã€ã¢ã³ããä¿®æ£ããã³æŽæ°ããŸãïŒè¿ãã®ãã¹ãŠã®ãšãŒãžã§ã³ããã¢ã»ããããã·ã¥ã«å¯ŸããŠãã¹ãŠåããã©ã¡ãŒã¿ïŒããã¯ã©ã€ã¢ã³ãèŠæ±ã®ãã®ã¹ããªãŒã ã¯ã2KBã®èŠæ±ã«å¿«é©ã«åãŸãå¯èœæ§ããããŸãã ãããŠãããã¯ã¢ããªã±ãŒã·ã§ã³ã¢ãŒããã¯ãã£ã«ãšã£ãŠæ©æµãããããŸããã
ç§ã¯ããªãã«RelayãšGraphQLã«ã€ããŠç§ãæè²ããããã«é Œãã€ããã¯ãããŸããã APIãå®å®ããããŒãžã§ã³ã«å°éããåã«ãè¡šé¢çã«èª¿ã¹ãã ãã§ãïŒçŸåšãããã¯ãããŠããŸããïŒïŒã³ã³ããŒãã³ãã䜿çšããŠãããŒã¿ã®äŸåé¢ä¿ãæå®ããGraphQLã¹ããŒããéžæããå®éã®ããŒã¿ããã§ããããå¿ èŠããããšç¢ºä¿¡ããŠããå Žåã¯ãããã¯è¯ãèšç»ã§ãããããŠå€åããã¯ç§ãããããããäžåºŠèŠçŽãæã§ãã ãã®ã¢ãŒããã¯ãã£ã«ã€ããŠããã€ãé£ãã質åããããŸããããããã¯ããå€ããããšããŠããŸãã
ïŒããŒã«ïŒ
PSç§ã¯HTTPãMMOFPSã®åªããéä¿¡ãããã³ã«ã«ãªãããšã瀺åããã€ããã¯ãããŸããã§ãã
@ d4goxnç§ã¯ããã«ã€ããŠã®ããªãã®èºèºãšæçè«ãå®å šã«ç解ããŠããŸãã GraphQLã®äœ¿çšãéå§ããåŸã§Relayã®æŠå¿µãå°å ¥ãããŸã§ãããã«ã€ããŠèããããšã¯ãããŸããã§ããã ãã²ã芧ã«ãªãããšããå§ãããŸãã ãŸããè€æ°ã®ããŒã¿ã¹ãã¢ãããå Žåã§ããæ°èŠãŸãã¯æ¢åã®ãµãŒããŒã«GraphQLãå®è£ ããããšã¯æ³åããã»ã©é£ãããããŸããã 話é¡ããå€ããããªãã®ã§ãããããã¯éèŠãªè°è«ã§ãã
ãã®ã¬ãã«ã®æœè±¡åãé²ãã¹ãéã ãšç§ã¯ä¿¡ããŠããŸãã ç§ã¯RelaxCMSã§ããã䜿çšããŠããŸããããã¯ãŒã¯ãããŒãšåé¢ã¯éåžžã«äŸ¿å©ã§ãã ããã ãã§ãªããèŠæ±ãããããŒã¿ã¯ãUIãå¿ èŠãšãããã®ãããå€ããå°ãªãããããŸãããããã¯ãåã³ã³ããŒãã³ããå¿ èŠãšããããŒã¿ãåéããŠããŒãžããããšã«ãã£ãŠèªåçã«äœæãããŸãã ãã§ãã¯ã«èå³ãããå Žåãããã¯Relatehttp ïŒ //relax.github.io/relate/how-it-works.htmlã«ãã£ãŠè¡ãããŸãã ããã«ãããã¢ããªã±ãŒã·ã§ã³ã®ã©ãã«ã§ãã³ã³ããŒãã³ããå«ããããšãã§ããã¢ããªã±ãŒã·ã§ã³ã®ç¬ç«ãããããã¯ãšããŠæ©èœããããšã確èªã§ããŸãã
ãŸã ç解ããŠããªãã®ã¯ããµãŒããŒåŽã®ã¬ã³ããªã³ã°ã ãã§ãã reactã®ãœãŒã¹ã³ãŒãã調ã¹ãåŸãç§ã説æããããã«ãã§ã«è§£æ±ºçããããããããªããšæããŸããããã§ãªããã°ãreactããŒã ã®èª°ããããã«åæããã°è§£æ±ºçã«åãçµãããšãã§ããŸãã
@ d4goxnç§ããããŠããªããšè°è«ããŸã:)ããªãã®å ã®æçš¿ã«ã¯ããã¥ãŒãããŒã¿ã®é¢æ°ã§ãããããŒã¿ãURLã®é¢æ°ã§ãããšããã¹ããŒãã¡ã³ããå«ãŸããŠãç»é¢ã«è¡šç€ºãããã®ã¯URLã®é¢æ°ã§ãããšãã
ç§ã«ãšã£ãŠã®äž»ãªè³ªåã¯ããã®ãããªé¢æ°ãã©ã®ããã«æ§ç¯ãããã§ãã
ããªããææ¡ããã¢ãããŒãã¯ãå€ãè¯ããµãŒããŒãµã€ãMVCã¢ããªã±ãŒã·ã§ã³ãšéåžžã«äŒŒãŠããããã«æããŸãïŒããšãã°ãSpring MVCãè¯ãäŸã§ãïŒã çŸåšã®URLã¯ã_ããžãã¹ããžãã¯ãå®è¡ãã_察å¿ããã³ã³ãããŒã©ãŒã¡ãœãããã¢ã¯ãã£ãã«ããŸãã å¿ èŠãªãã¹ãŠã®ããŒã¿ããã§ããããŠããããããã¥ãŒã«æž¡ããŸãã ããã«é¢ããç§ã®åé¡ã¯æ¬¡ã®ãšããã§ããçæãããWebããŒãžãèŠããšãããã¯ã³ã³ããŒãã³ãã®ããçš®ã®éå±€ã§ãïŒå¿ ãããReactã³ã³ããŒãã³ãã§ããå¿ èŠã¯ãããŸããïŒã ããªããããªããã°ãªããªãããšã¯ãURLããéå±€ãäœæãŸãã¯çæããããšã§ãã ããããããªãã¯ãããäºåºŠããªããã°ãªããŸããïŒ ãŸããã³ã³ãããŒã©ãŒã§éå±€ããã³ãŒãããŠããã§ããããå¿ èŠã®ããããŒã¿ãç¥ãå¿ èŠããããŸãã次ã«ããã¥ãŒã®éå±€ããã³ãŒãããŠãå®éã®ãã¥ãŒãã¬ã³ããªã³ã°ããå¿ èŠããããŸãã ããŸã_DRY_ã¢ãããŒãã§ã¯ãªããšæããŸãã
ç§ã¯SpringMVCã«ããŸã詳ãããããŸããããReactã®äœ¿çšæ¹æ³ãšéåžžã«ãã䌌ãæ¹æ³ã§ãã®åé¡ã«å¯ŸåŠããå¥ã®MVCãã¬ãŒã ã¯ãŒã¯ïŒNetteãšåŒã°ããPHPãã¬ãŒã ã¯ãŒã¯ïŒãé »ç¹ã«äœ¿çšããŸãã ãã®ãã¬ãŒã ã¯ãŒã¯ã¯ã³ã³ããŒãã³ãããµããŒãããŸãã ã¢ã€ãã¢ã¯ãã³ã³ããŒãã³ãïŒãã©ãŒã ãªã©ïŒããšã«ãã³ã³ããŒãã³ãã®ã€ã³ã¹ã¿ã³ã¹åãç¹ã«_å¿ èŠãªãã¹ãŠã®ããŒã¿ã®ããŒã_ãæ åœãããã¡ã¯ããªãã³ãŒãã§å®çŸ©ããããšã§ãã ãã®ãããªã³ã³ããŒãã³ãã¯ããã¥ãŒã®ã©ãã«ã§ãå«ããããšãã§ããŸãã ãããã£ãŠãHTMLã³ãŒããèšè¿°ããŠ_ãã¥ãŒéå±€_ãäœæãããšãã«ãã³ã³ããŒãã³ããæ¿å ¥ããã ãã§ãåºç€ãšãªããã¡ã¯ããªãå¿ èŠãªåæåãåŠçããŸãã ã³ã³ããŒãã³ãã¯å°ããªç¬ç«ããã³ã³ãããŒã©ãŒã®ããã«åäœããç¬èªã®ã©ã€ããµã€ã¯ã«ãæã¡ãäŸåé¢ä¿ãåŠçãããã¥ãŒãããã©ã¡ãŒã¿ãŒåããããšãã§ãããããåå©çšæ§ãåäžããŸãã
ç§ã¯ã¯ã©ã€ã¢ã³ãåŽã§ãReactã§ãã®ã¢ãããŒãã䜿çšããŠããŸããããéåžžã«å®è¡å¯èœã®ããã§ãã Reactã³ã³ããŒãã³ãã¯æåãã_controller-views_ãšããŠç€ºãããŠããŠããããç§ããããã䜿çšããæ¹æ³ã§ãã ããŒã¿ãã§ãããæ åœãã_controller_ã³ã³ããŒãã³ããããã次ã«ããžã¥ã¢ã«ã®ã¿ãæ°ã«ãã_view_ã³ã³ããŒãã³ãããããŸãã ããŒãžå šäœã¯ãäž¡æ¹ã®ã¿ã€ãã®ã³ã³ããŒãã³ãã§æ§æãããŠããŸãã ãããã¯ããŸãåé¢ãããŠãããç°¡åã«åå©çšã§ããŸãã
ç§ã®ã¢ããªã±ãŒã·ã§ã³ã¯ãå¿ èŠããªãã£ãã®ã§å圢ã§ã¯ãããŸããïŒãŸãã¯ä»æ¥ã§ã¯ãŠãããŒãµã«ãšåŒã°ããŠããŸãïŒãã䜿çšããŠããã¹ã¿ãã¯ã¯ãããå¯èœã§ããå¿ èŠããããŸãïŒãããŠããŸã å®éšçãªãªã¬ãŒãé€ããŠããã®ã¹ã¿ãã¯ã¯ãã®åé¡ã®æé·ãã¹ïŒã åèãŸã§ã«ã次ã®ããã«ãªããŸãã
react-router
ã®èšèšã§ãã ããã«ããã_data-hierarchy_ãš_view / componenthierarchy_ã®äž¡æ¹ãåãå Žæã§å®çŸ©ã§ããå®éã®ã«ãŒãå®çŸ©ãéå±€åãããŸãã ãšãŠã_Reactã®ããã«_æããŸããconnect()
ã¢ãããŒãã®ãããã§ãå°éå
·ã䜿çšããŠãããã¬ãã«ãããã¹ãŠã®ããŒã¿ãæž¡ãå¿
èŠã¯ãããŸããïŒç§ã®ã¢ããªã±ãŒã·ã§ã³ã®çŸåšã®ãµã€ãºãèãããšãããã¯çµ¶å¯Ÿã«ã¯ã¬ã€ãžãŒã§ãïŒãããã¯ãŸã å®ç§ã§ã¯ãããŸããããç§ããã®ã¹ã¬ããã«æåã«åºãããããšãã«å©çšå¯èœã ã£ããã®ããã®éèŠãªé²æ©ã§ãã ãµã³ãã«ã®å®è£ ã¯ããã«ãããŸãã
ããŒã¿ãã§ãããã³ã³ããŒãã³ãã¬ãã«ã§ãããšãã«ãµãŒããŒåŽã®ã¬ã³ããªã³ã°ãå®è¡ããæ¹æ³ãå¿ èŠãªå Žåãé€ããŠãç§ãã»ãŒãã¹ãŠã®å圢åäœãè¡ã£ãŠããŸãã ä»ã®ãšããå²åŠçãªè°è«ã«è¿œå ããããšãªããç§ã¯é·ãéãcomponentDidMountã§ç¬èªã®ããŒã¿ããã§ããããã³ã³ããŒãã³ãã§ããã©ãªã¢ã¯ã·ã§ã³ïŒããã³èªå®¶è£œã«ãŒãã£ã³ã°ïŒãããŸã䜿çšããŠããŸããã ã³ã³ããŒãã³ããšããŒã¿ã®äŸåé¢ä¿ãå®çŸ©ããããã«åé·ãªæ§é ãç¶æãããšããã¢ã€ãã¢ã¯æ¬åœã«å«ãã§ããããã¯ã³ã³ããŒãã³ãããªãŒã§ãã§ã«å®çŸ©ãããŠããŸããããã§ã¯ãå®å šãªã³ã³ããŒãã³ãã«ãªããŸã§ãéåæã§ãã§ãããããããŒã¿ãçµã¿èŸŒãè€æ°ã®ã¬ã³ããªã³ã°ãã¹ãå¿ èŠã«ãªãå¯èœæ§ããããŸããããªãŒã解決ãããŸããã
ä»ã®ãšãããç§ã¯ãã¢ã€ãœã¢ãã£ãã¯ãªåå¿ãimoã«ãšã£ãŠããã®éèŠæ§ãé«ãŸã£ãŠããããšã2çªç®ã«ãããã£ãã ãã§ãã ãããŸã§ã®éã解決çã暡玢ããŸãã ããããšãã
@decodemanèå³ãããå Žåã¯ã
@ decodeman ãFWIWã¯ã倧èŠæš¡ãªæ¬çªã¢ããªã§ïŒããªãããã®redux-sagaã®äŸã«è§ŠçºãããŠãcomponentWillMount
ã«ç§»åããå¿
èŠããããŸãã 管çããããããããã«ãäžè¬çãªèªã¿èŸŒã¿ã·ããªãªãåŠçããé«æ¬¡ã®ã³ã³ããŒãã³ãããããŸãïŒããšãã°ãprop x
ã確èªããnilã®å Žåã¯èªã¿èŸŒã¿ãŸãã
ãŸããã³ã³ããŒãã³ãå
ã«ããŒã¿ãããŒãããããçš®ã®ã¬ã€ãžãŒã¬ã³ããªã³ã°ã¡ãœããã䜿çšã§ããããšãéåžžã«éèŠã ãšæããŸãã ãããããåæ¹ãæºè¶³ãããããã«ãasyncRenderToStringãšåŒã°ããæ°ããã¡ãœãããäœæãã asyncOnLoad
ãªã©ãšåŒã°ããæ°ãããã©ã€ããµã€ã¯ã«ãã€ãã³ããè¿œå ããŸãã ããã¯ãasyncRenderã¡ãœãããåŒã³åºãå Žåã«ã®ã¿åŒã³åºãããŸãã ãµãŒããŒåŽãšã¯ã©ã€ã¢ã³ãåŽã®éã®ã³ãŒãã®éè€ã«é¢ããŠãããã¯ãäžè¬çãªèªã¿èŸŒã¿ã³ãŒããå¥ã®ã¡ãœããã«ç§»åãããã®ã¡ãœãããasyncOnLoad
ãšcomponentMount
ããåŒã³åºãéçºè
ã«ãã£ãŠä¿®æ£ã§ããŸãã asyncOnLoadãå®è¡ããããã©ããã®æ€åºã§ã¯ãããããè¿ãããPromiseã䜿çšããå¿
èŠããããŸãïŒæªå®çŸ©ãè¿ããã/ã¡ãœãããå®çŸ©ãããŠããªãå Žåã¯ã該åœããã©ã€ããµã€ã¯ã«ã€ãã³ããçŽæ¥åŒã³åºããŠããã¬ã³ããªã³ã°ããå¿
èŠããããŸãïŒããã以å€ã®å Žåã¯ãPromiseã解決ãããŸã§åŸ
æ©ããŸãã
ãã®ãããªè§£æ±ºçã¯ãé©åãªãµãŒããŒåŽã®ã¬ã³ããªã³ã°ã®ããã«çŸæç¹ã§äœ¿çšããªããã°ãªããªããã¹ãŠã®ããããŒãªæ¹æ³ã解決ãããšæããŸãã ããšãã°ãreact router v4ã䜿çšããŠreactã¢ããªã±ãŒã·ã§ã³ã®ãµãŒããŒåŽã§ã®ã¬ã³ããªã³ã°ãç°¡åã«è¡ããããã«ããŸãïŒå圢ã¢ããªã±ãŒã·ã§ã³ãæ©èœãããå¯äžã®æ¹æ³ã§ããéäžã«ãŒãæ§æã䜿çšããªããªããŸããïŒ
ããã¯ãããããã¹ããªãŒã ãã§ãã¯ã¢ãŠãåå¿ã¹ããªãŒã ã§è§£æ±ºãããŸããã
2016幎11æ3æ¥ïŒæšææ¥ïŒã«ã¯ããããªã¢ã³Krauthan [email protected]
æžããŸããïŒ
ãŸããå ã«ããŒã¿ãããŒãã§ããããšã¯éåžžã«éèŠã ãšæããŸã
ã³ã³ããŒãã³ããšããçš®ã®æ æ°ãªã¬ã³ããªã³ã°ã¡ãœããããããŸãã å€åäž¡æ¹ãäœãããã«
ãµã€ãããããŒasyncRenderToStringãšåŒã°ããæ°ããã¡ãœãããäœæããæ°ãã
asyncOnLoadãªã©ãšåŒã°ãããã©ã€ããµã€ã¯ã«ãã€ãã³ãã ãã®æå¿
asyncRenderã¡ãœãããåŒã³åºãå Žåã«ã®ã¿åŒã³åºãããŸãã ã³ãŒãã«é¢ããŠ
ãµãŒããŒåŽãšã¯ã©ã€ã¢ã³ãåŽã®éã®éè€ããã¯éçºè ãä¿®æ£ã§ããŸã
äžè¬çãªèªã¿èŸŒã¿ã³ãŒããå¥ã®ã¡ãœããã«ç§»åããŠããããåŒã³åºãã ãã§ãã
asyncOnLoadããã³componentMountããã®ã¡ãœããã asyncOnLoadã
ãããããè¿ãããPromiseã䜿çšããå¿ èŠããããŸãïŒæªå®çŸ©ã®å Žå
è¿ããã/ã¡ãœãããå®çŸ©ãããŠããªãå Žåã¯ã該åœãããã®ãçŽæ¥åŒã³åºãå¿ èŠããããŸã
ã©ã€ããµã€ã¯ã«ã€ãã³ããšã¬ã³ããªã³ã°ïŒãã以å€ã®å Žåã¯ãçŽæãŸã§åŸ æ©ããŸã
解決ããŸãããã®ãããªè§£æ±ºçã¯ãç§ãã¡ã䜿çšããªããã°ãªããªããã¹ãŠã®ããããŒãªæ¹æ³ã解決ãããšæããŸã
çŸæç¹ã§ã¯ãé©åãªãµãŒããŒåŽã®ã¬ã³ããªã³ã°ãå¿ èŠã§ãã ããšãã°èš±å¯ãå«ã
react routerv4ã䜿çšããreactã¢ããªã±ãŒã·ã§ã³ã®ãµãŒããŒåŽã§ã®ç°¡åãªã¬ã³ããªã³ã°
ïŒããã¯ãçŸåšã®éäžã«ãŒãèšå®ã䜿çšããªããªããŸãã
å圢ã¢ããªã±ãŒã·ã§ã³ãæ©èœãããå¯äžã®æ¹æ³ïŒâ
ãã®ã¹ã¬ããã«ãµãã¹ã¯ã©ã€ãããŠããããããããåãåã£ãŠããŸãã
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/facebook/react/issues/1739#issuecomment -258198533ã
ãŸãã¯ã¹ã¬ããããã¥ãŒãããŸã
https://github.com/notifications/unsubscribe-auth/ATnWLUIEJw4m1Y3A4oGDOBzP6_ajDcqIks5q6g4_gaJpZM4CHAWq
ã
@ yamat124åå¿ã¹ããªãŒã ãæ€çŽ¢ãããšããã®ãããžã§ã¯ãã®ã¿ãèŠã€ãããŸãïŒ https ïŒ
å°ãªããšãããã¥ã¡ã³ãã«åºã¥ããšãããŒã¿ãããªããŒãããããã®ã©ã€ããµã€ã¯ã«ã€ãã³ããèšå®ããŠãPromiseã解決ããããŸã§ãµããã£ã€ã«ãã®æ¬¡ã®ã¬ã³ããªã³ã°åŒã³åºããé ãããæ¹æ³ã¯ãããŸããã ãããšãäœãä»ã®ããšã«ã€ããŠè©±ããŠããã®ã§ããïŒ
ç¹°ãè¿ããŸãããããã¯ãã¹ãŠéåžžã«ããããŒãªæ¹æ³ã§ãã ã³ã³ããŒãã³ãããªãŒããç¬ç«ããã«ãŒãã£ã³ã°ãå¿ èŠã§ãã ãŸããã«ãŒãã«å«ãŸãããã¡ã€ã³ãã³ã³ããŒãã³ãã¯ãããŒãããå¿ èŠã®ãããã¹ãŠã®ããŒã¿ãèªèããŠããå¿ èŠããããŸãïŒ99ïŒ ã®æéã§æ©èœããŸãããåžžã«æ©èœãããšã¯éããŸããïŒã reactã®ã³ã³ããŒãã³ãã¬ã³ããªã³ã°ãé ããŠããå Žåãäž¡æ¹ãšãå»æ¢ãããŸãã
ç§ã¯åæããŸããããã¯ããããç§ãä»åå¿ã«ã€ããŠæãå«ããªããšã§ãã æåã§å®è¡ã§ãããšèšã£ãŠããã¬ãŒã ã¯ãŒã¯ããã®æ©èœãæããªãããã«é²åŸ¡ããããšããã®ã¯å«ãã§ãããã¡ããããœãããŠã§ã¢éçºã«é¢é£ãããã¹ãŠã®ãã®ãšåæ§ã«ããã¬ãŒã ã¯ãŒã¯ã¯å¯èœã§ãããããããå¿ èŠããããšããæå³ã§ã¯ãããŸããã ãã®æ£ç¢ºãªããšèªäœãããã¬ãŒã ã¯ãŒã¯èªäœã®å éšãã解決ãããã¹ããã®ã§ããããšãææããå¿ èŠããããã©ããã«æ³šæãæã£ãŠããã¢ãžã¥ãŒã«ããããããããšããäºå®ã
Next.jsã«ã¯ããµãŒããŒåŽã®ã¬ã³ããªã³ã°ãè¡ãããã®async getInitialProps
ããããŸãããæ®å¿µãªããã芪ããã«ãŒããŸã§ãã£ãšåã®getInitialProps
ãåŒã³åºãå¿
èŠããããŸãã Apollo GraphQLã¯ã©ã€ã¢ã³ãã§ã¯ããã¹ãŠã®ããªãŒããã©ããŒã¹ããŠãµãŒããŒåŽã®ããŒã¿èŠä»¶ãåéãããã¹ãŠãéãè¿ãããšãã§ããŸãã Next + Apolloã®äŸïŒ https ïŒ
ããããçµã¿åãããããã®éåæReactã³ã³ããŒãã³ãã©ã€ããµã€ã¯ã«ã¡ãœããããããšäŸ¿å©ã§ãã
ä»é±SSRã«ã€ããŠåŠãã ã°ããã§ãããç§ãæžãããã®ãçã«ããªã£ãŠããããšãé¡ã£ãŠããŸãð
/ cc @nkzawa @stubailo
ãšããã§componentWill/DidMount
ã¯ãã§ã«éåæã§ããããã¯åœ¹ã«ç«ã¡ãŸããïŒ
@sedubois Reactã¯ãã¬ã³ããªã³ã°ããåã«Promiseã解決ããã®ãåŸ ã¡ãŸããïŒ ããã§ãªããã°ãæ¬åœã«å©ãã«ã¯ãªããŸããïŒ
@olalondeããã§ãïŒ https ïŒ
const getMessage = async () => new Promise((resolve) => {
setTimeout(() => {
resolve('Got async message!');
}, 3000);
});
class App extends Component {
state = {
message: 'Loading...',
};
async componentWillMount() {
this.setState({ message: await getMessage() });
}
render() {
return (... {this.state.message} ...);
}
}
@seduboisããªãã®äŸã§ã¯ã componentWillMount
泚æããŠãã ãã
async componentWillMount() {
this.setState({ message: await getMessage() });
}
promiseãè¿ããŸãããã¹ã¯ãªãŒã³ã·ã§ããã¯ãReactãundefined
ãšLoading...
ããã¹ããã¬ã³ããªã³ã°ãããããpromiseãåŸ
æ©ããªãïŒåŸ
æ©
ç·šéïŒä¿®æ£ã
@sedubois @polytypic Promiseã¯ãŸã£ããåŠçãããªããããé¢æ°å ã§ã¹ããŒããããã¹ãŠã®ãšã©ãŒãé»ã£ãŠç¡èŠãããåå ã«ããªããŸãã
@ polytypic @ dantman ãçŽæããŸã£ããåŠçãããªãããšã¯ã©ãããæå³ãããawait
æŒç®åãåŸ
æ©ããŠããŸãã ãšã©ãŒããã£ããããå¿
èŠããããŸããäŸãæŽæ°ããŸããïŒApolloãšåæ§ã®èªã¿èŸŒã¿/ãšã©ãŒã·ã°ããã£ã䜿çšïŒã
try {
this.setState({ message: await getMessage() });
} catch(error) {
this.setState({ error });
}
ãããŠã¬ã³ããªã³ã°ïŒ
{error ? error : loading ? 'Loading...' : message}
@seduboisé¢æ°ãasync
ãããšãæé»çã«promiseãè¿ãããé¢æ°å
ã®throw
ã¯ãã¹ã¿ãã¯ãã¹ããŒããã®ã§ã¯ãªããæé»çã«ãã®promiseã®æåŠã«ãªããŸãã ããã¯ã componentWillMount
ãåŒã³åºãå
ã«promiseãè¿ããŠããããšãæå³ããŸãã
Reactã¯æ»ãå€ã«å¯ŸããŠäœãããªãã®ã§ãé¢æ°ã¯èª°ããããã䜿ã£ãŠäœããããŠããããšãæåŸ ããŠPromiseãè¿ããŸããã代ããã«æšãŠãããŠããã ãã§ãã
åŠçãããªãããããã®çŽæã®æåŠã¯Reactã®ã³ãŒãã«ãã£ãŠãã£ããããããæªåŠçã®ãšã©ãŒã¯ã³ã³ãœãŒã«ã«è¡šç€ºãããŸããã
ãããŠãtry..catchãå®è¡ããŠããããããå®å
šã«ä¿è·ããããšã¯ã§ããŸããã setState
ããã£ãããããšã©ãŒãã¹ããŒããå ŽåããŸãã¯ãã£ããã§ã¿ã€ããã¹ãããå Žåããã®ãšã©ãŒã¯é»ã£ãŠæ¶ããäœããå£ããŠããããšã«æ°ä»ãããšã¯ãããŸããã
@seduboiså®éãéåæã¡ãœããã¯åžžã«JavaScriptïŒãŸããå°æ¥ã®JavaScriptïŒã§promiseãè¿ãããã«èŠããŸãã CïŒã§ã®async-awaitã®åé¡ã«ã€ããŠèãããšæ··ä¹±ããŸããã _éšé³ã«ã€ããŠãè©«ã³ããŸãïŒ_
ããã«ãããããããã¹ã¯ãªãŒã³ã·ã§ããã¯ãReactãçŽæã解決ãããã®ãåŸ
ããªãããšãæ確ã«ç€ºããŠããŸãã componentWillMount
ãåŒã³åºããçŽåŸã«render
ãåŒã³åºãã Loading...
ããã¹ããã¬ã³ããªã³ã°ããŸãã 次ã«ã setState
åŒã³åºããåŸãåã³render
åŒã³åºããŸãã ReactãçŽæã®è§£æ±ºãåŸ
ã£ãŠããå Žåã Loading...
ããã¹ãã¯ãŸã£ããã¬ã³ããªã³ã°ãããŸããã 代ããã«ãpromiseã解決ãããŸã§åŸ
æ©ãã render
åŒã³åºãã ãã§ããããã¯ããã®åé¡ã®ãã¹ãŠã®åäœã®äžçš®ã§ãããµãŒããŒåŽã®ã¬ã³ããªã³ã°äžã«éåæIOãå®è¡ã§ããããã«ããããã§ãã
@dantman @ polytypicthanksðã¯ããå¿çãåŸ
ã£ãŠãšã©ãŒãé©åã«åŠçããã«ã¯ãReactå
ã§å€æŽãå¿
èŠã§ããããšã確èªããŠãã ããã ãã¶ããã³ãŒãã®ãã¡ãã¡ã«await
è¿œå ãããšããããå¯èœã«ãªããŸãð
å人çã«ã¯ãWebã¯ãŒã«ãŒã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ã®ç¶æ ãä¿åããå€æŽæã«å°éå ·ãåºåããŸãïŒããŒã¿ã¹ãã¬ãŒãžãšReactã³ã³ããŒãã³ãããã®ãã§ãããå®å šã«åãé¢ããReactãã¬ã³ãã©ãŒãšããŠæ±ããäžæ¹åã®ãããŒã®ååãç¶æããŸãïŒãã¬ã³ããªã³ã°ããããã«æåŸ ãããèŠä»¶ïŒç¹å®ã®ããããã£ãtrueã§ãããªã©ïŒãå«ãã¡ãã»ãŒãžã
ããããã°ãæåã®ã¡ãã»ãŒãžãäžéã®ãèªã¿èŸŒã¿äžãã®ç¶æ ã§ãã£ãŠããéåæã³ã³ããŒãã³ãã¡ãœãããå¿ èŠãšããã«ãéçãªãµãŒããŒåŽã®ã¬ã³ããªã³ã°ã«ã¯äœ¿çšãããŸããã
@seduboisã¡ãœããã®å¥ã®ã¹ã¿ãã¯ã§ããå¿ èŠããããŸãã ãŸãã¯é倧ãªå€æŽã Reactã®çŸåšã®ã¬ã³ããªã³ã°ã¡ãœããã¯åæãããŠãããããpromiseãè¿ãå¥ã®ãµãŒããŒã¬ã³ããªã³ã°ã¡ãœãããå¿ èŠã«ãªããŸãã
@dantmanãããã®æ°Žåã¯ç§ã«ã¯æ·±ãããã®ã§ãããã§ã¯æèŠãè¿°ã¹ãããããŸããïŒç§ã®æåã®ç®çã¯ãVjeuxã®éåæã³ã³ããŒãã³ãWillMountããã¯ãææããããšã§ãã...ïŒãããããããŒããReactã¯ã¿ã€ããèŠãããšãã§ããŸããã©ã€ããµã€ã¯ã«ã¡ãœããã«ãã£ãŠè¿ããããªããžã§ã¯ãããããpromiseã®å Žåã¯ãéåæã§åŠçãããã以å€ã®å Žåã¯åæã§åŠçããŸãïŒçŸåšã®ããã«ãã€ãŸãäžäœäºææ§ã®ããæ¹æ³ã§ïŒïŒ
@fkrauthanãææ¡ãããã®ãundefined
ãšè¿œå ã®éåærenderToStringAsync
é¢æ°ãè¿ãããšãã§ããã©ã€ããµã€ã¯ã«ã¡ãœããload
ã ãã ãã load
ã¯ãã¯ã©ã€ã¢ã³ããšãµãŒããŒã§åžžã«åŒã³åºãå¿
èŠããããŸãã render
ãŸãã¯renderToString
ã䜿çšããå Žåãè¿ãããpromiseã¯ç¡èŠãããçŸåšã®åäœãšäžèŽããŸãã renderToStringAsync
ã䜿çšãã load
ãpromiseãè¿ãå Žåãã¬ã³ããªã³ã°ããåã«promiseã解決ããå¿
èŠããããŸãã
Next.jsã奜ãã§ã¯ãªãã®ã¯ãªãã§ãããã³ã³ã¹ãã©ã¯ã¿ãŒã®åã«åŒã³åºãããReact async getInitialProps
ã©ã€ããµã€ã¯ã«é¢æ°ãè¿œå ããŸããïŒ ãã®ãããªã¡ãœããããªãå Žåã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒãçŽæ¥åŒã³åºããŸãã
const props = await (Component.getInitialProps ? Component.getInitialProps(ctx) : {});
...
const app = createElement(App, {
Component,
props,
...
});
Next.jsã¯ããã®getInitialProps
ãReactã³ã³ããŒãã³ãã®ã©ã€ããµã€ã¯ã«ã«ããã¯ãããŠããªããããæäžäœã®ã³ã³ããŒãã³ãã§ã®ã¿åŒã³åºãããšãã§ããããšãé€ããŠããªããšãä»äºãããŠããããã«èŠããŸãã ããã§ãã¢ã€ãã¢ã¯ããã«ããããã äžç·ã«çµåããããšãã§ããŸããïŒ
@seduboisgetInitialPropsãæ£ããå Žæã§ã¯ãªããšæããŸãã ãŸã第äžã«ãES6ã䜿çšããŠãã人ã
ã¯ããã®æ¹æ³ãæã£ãŠããªã/䜿çšããŠããŸããã 第äºã«ãããªãã¯initalPropsïŒããã¯åãªãããã©ã«ãã§ãïŒã§äœæ¥ããããªãã®ã§ãããinitalPropsãšæž¡ãããå°éå
·ã®ããŒãžã®äžã§äœæ¥ãããã®ã§ãã ãã®ããã componentWillMount
åã«ãã£ã¹ããããããæ°ããã©ã€ããµã€ã¯ã«ã€ãã³ãã®ææ¡ã
@ Lenne231ã®ã¢ã€ãã¢ã¯ãä»ã®ã©ã€ããµã€ã¯ã«ã€ãã³ããäžç¶ããŠããã®çŽæããã§ã«è§£æ±ºãããŠããå¯èœæ§ããããããããã€ãã®åé¡ãåŒãèµ·ããå¯èœæ§ããããšæããŸãã åãã©ã€ããµã€ã¯ã«ã€ãã³ãã®2ã€ã®ç°ãªãåäœããããšãå°ã泚æãå¿ èŠã«ãªããŸãã
ãã®ããããµãŒããŒãšã¯ã©ã€ã¢ã³ãã«ã¯ããã®æ°ããã©ã€ããµã€ã¯ã«ããŸã£ããåŒã³åºããªã1ã€ã®åæã¬ã³ããªã³ã°ã¡ãœãããå¿ èŠã§ãã ãããŠããã®ã©ã€ããµã€ã¯ã«ãåŒã³åºããpromiseã解決ããããŸã§åžžã«åŸ æ©ããŠããç¶è¡ããéåæããŒãžã§ã³ã ç§ã®æèŠã§ã¯ãã¯ã©ã€ã¢ã³ãã¬ã³ããªã³ã°ã§ãã©ã€ããµã€ã¯ã«ãå¿ èŠãããµãŒããŒã¬ã³ããªã³ã°ã ãã§ã©ã€ããµã€ã¯ã«ãå¿ èŠããå€æã§ãããããæ倧ã®æè»æ§ãåŸãããŸãã
ES6ã䜿çšããŠãã人ã¯ããã®æ¹æ³ãæã£ãŠããªã/䜿çšããŠããŸãã
@fkrauthanå€åããªãã¯getInitialState
ãåç
§ããŸããïŒ ããã§ç§ã¯æ°ãããã®ã getInitialProps
ïŒNext.jsã§äœ¿çšãããååïŒã«ã€ããŠè©±ããŠããŸããã
2çªç®ã®ãã€ã³ãã«ã€ããŠã¯ãã¯ãã constructor
åã§ã¯ãªãã componentWillMount
åã«æ°ããã©ã€ããµã€ã¯ã«ã¡ãœããã䜿çšããæ¹ãããå ŽåããããŸãã å
ã«è¿°ã¹ãããã«ãReactã®ã©ã€ããµã€ã¯ã«ã埮調æŽããäœè£ããªããããNextã§ã¯ããã§ã¯ãªããšæããŸãã ãããã£ãŠããªããããã®ã¢ã€ãã¢ãReactã«åãå
¥ããããšãçŽ æŽãããã®ã§ããããã
@seduboisããã§ãã ããšãã°ães7æ©èœã䜿çšããŠãã¯ã©ã¹æ¬äœã§static props = {};
ãå®çŸ©ããŸãã ããã«ãããç§ã®æèŠã§ã¯ã³ãŒããèªã¿ããããªãães7ãæ£åŒã«ãªãªãŒã¹ããããšããã«ããŸããŸãå€ãã®äººãã³ãŒãã«åãæ¿ããããã«ãªããšç¢ºä¿¡ããŠããŸãã
泚ïŒES7ã¯ãã§ã«å®æããŠãããæ°ããèšèªæ©èœã¯ã¹ãä¹æŒç®åã®ã¿ã§ãããããã¯ã©ã¹ããããã£ã¯ãES7ãæ©èœã§ã¯ãããŸããã ããªããåç §ããŠããã®ã¯ãã¹ããŒãž2ã¯ã©ã¹ã®ããããã£ã®ææ¡ã§ãã ããã¯ãŸã èšèªã®äžéšã§ã¯ãªããå€æŽãããããåé€ããããããå¯èœæ§ããããŸãã
ããŒã¿ããã§ããããããã«åå¿ããéåæé¢æ°ã®å¿ èŠæ§ã¯ããããŸããã代ããã«ããªã³ããã³ãã§renderToStringãå®è¡ããä»®æ³ã¬ã³ãã©ãŒã«æºè¶³ããŠããŸãã ãããã£ãŠãã¢ã¯ã·ã§ã³ãèšå®ãããšãæååã«ã¬ã³ããªã³ã°ããåã«ä»®æ³ããªãŒãããã«å¿ããŠæŽæ°ãããŸãã ããã¯ãåå¿ã«ãããŠåªããSSRãéæããããã«çæ³çã ãšæããŸãã ããŒã¿ãååŸããæ¹æ³ãšå Žæã¯éçºè ã«ä»»ãããŠããŸãã
ç§ã¯åã«è¿°ã¹ãŸããããè¯ãAPIã¯æ¬¡ã®ãããªãã®ã«ãªããŸãïŒç§ã以åã«ææ¡ãããã®ã§å°ãæŽæ°ãããŠããŸãïŒïŒ
const virtualTree = ReactDOM.renderVirtual(rootEle);
// get the bundled query from redux store for example
const bundle = store.getState().bundle;
// Fetch the data according to the bundle
const data = await fetchDataSomehow(bundle);
// hydrate store (this will set updates on the virtual tree)
store.dispatch({type: 'hydrate', data});
// final result
const domString = virtualTree.renderToString();
ããã«ãããApolloãªã©ã®äžéšã®GraphQLã¯ã©ã€ã¢ã³ãã§çºçããŠãããããã«renderToStringãäœæããããã«åŒ·å¶ããåé¡ãåé¿ã§ããŸãã ããŒã¿ã®äŸåé¢ä¿ãæåã«ãã§ããããããŒã¿ãå ¥åãããç¶æ ã§2çªç®ã«ã¬ã³ããªã³ã°ããŸãã renderToStringã¯éåžžã«é«äŸ¡ãªã®ã§ãããã¯åŠçã®ç¡é§ã ãšæããŸãã
@ bruno12motaç§ã¯ããªãã®ç解ããŠããŸããããããã·ãã¥ã¬ãŒãããããšããã©ã€ãã©ãªã®éïŒãããŠããªãã®ãœãªã¥ãŒã·ã§ã³ã§ã¯ãŸã äœåãã®ã©ã€ãã©ãªããããŸãïŒã¯ããããããããããªããããªããã°ãªããªããã®ã§ã¯ãªãã³ã¢æ©èœã§ããã¹ãã ãšããå åã§ãäžã«æ§ç¯ããŸãã ããªãã®ãœãªã¥ãŒã·ã§ã³ã¯ãåºåãååŸããããã«ãã¯ããã«å€ãã®ã¬ã³ããªã³ã°åŒã³åºãïŒä»®æ³ã§ãããã¬ã³ããªã³ã°åŒã³åºãïŒãå¿ èŠãšããŸãã
@fkrauthanã¯ãããã ããä»®æ³ã¬ã³ããªã³ã°ã¯ãæååã«å¯ŸããŠ2ã€ã®ã¬ã³ããªã³ã°ãè¡ããããã¯ããã«ããã©ãŒãã³ã¹ãé«ãããããç§ã®æèŠïŒSSRã§ã®ããã©ãŒãã³ã¹ïŒã®äž»ãªåé¡ã§ãããReactã®åŒ±ç¹ã§ãã reactã®renderToString
ãæ¹åããããã®ããã€ãã®å®éšããããŸããããreactããŒã ã«ãããã®åé¡ã®å®éã®é²æ©ã¯ãããŸããïŒããã§æ¹å€ããããšã¯ãããŸããã圌ãã¯çŽ æŽãããä»äºãããŠããŸãïŒã
ç§ã¯@ bruno12motaã«åæããŸãããã®åé¡ã«ã€ããŠããã°ããã®éæ€èšããŠããŸãããããããæãç°¡åãªã¢ãããŒãã§ãã ã¬ã³ããªã³ã°ããã€ããã©ãã·ã¥ããããã決å®ããèªç±ã¯éçºè ã«ãããŸãã
ããã¯ãã¹ãŠãã¯ããã«è€éã«ããŸãã
1.ïŒã³ãŒãã®èŠ³ç¹ããïŒã³ãŒãã調ã¹ãŠãã¬ã³ããªã³ã°ãéåæã«ããæ¹ããVDomã䜿çšããã ãã§ãããæç¹ã§ãã³ãã§ããã¬ã³ãã©ãŒãäœæãããããã¯ããã«ç°¡åãªã¯ãã§ãïŒ
2.ïŒããã§ãã¢ã³ããŠã³ãã€ãã³ããåæ€èšããå¿
èŠããããŸãã ãŸããã«ã¹ã¿ã ã³ãŒããå¿
èŠä»¥äžã«è€éã«ãªããŸãã ããšãã°ãããŒã¿ãããŒããããšãããŒã¿ãããŒãããå¿
èŠãããæ°ããã³ã³ããŒãã³ããã¬ã³ããªã³ã°ãããå¯èœæ§ããããŸãã ããã§çªç¶ãlibã¯ãã©ã®ã³ã³ããŒãã³ããã©ã®äœçœ®ã«ãã§ã«ããŒã¿ãããŒãããŠããããã©ã®ã³ã³ããŒãã³ãã«æ°ããããŒã¿ã®ããŒããªã©ãå«ãŸããŠããããææ¡ããå¿
èŠããããŸãã
ç§ã¯@ bruno12motaãšäžç·ã§ãã VDomã¯ééããªããããäœã¬ãã«ãã®ãœãªã¥ãŒã·ã§ã³ã§ãããReactéçºè ã«ãšã£ãŠã¯å®è£ ãç°¡åã§ãããäžäœäºææ§ã®åé¡ããªããã³ãã¥ããã£ãããŸããŸãªé«ã¬ãã«ã®ãœãªã¥ãŒã·ã§ã³ãè©Šãããšãã§ããŸãã
ããšãã°ã1ã€ã®é«ã¬ãã«ã®ãœãªã¥ãŒã·ã§ã³ã¯ãéåæcomponentWillMount
ã¡ãœãããã©ãããããã¹ãŠã®ä¿çäžã®promiseãåŸ
æ©ãããã¹ãŠã解決ããããšãã«VDom.renderToString()
èµ·åãããé«ã¬ãã«ã³ã³ããŒãã³ããã§ããå¯èœæ§ããããŸãã ç§ã¯ã¢ããªã§SSRã«ãã®çš®ã®æŠç¥ã䜿çšããŠããŸãããVDomããªããããæ®å¿µãªããçŸåšå€ãã®ãªãŒããŒãã§ãããè¡ã£ãŠããŸãã
çŸåšæã£ãŠããæ©èœãå€ããªãã®ãäžçªããæ¹æ³ã ãšæããŸãã ããã¯ãgetInitialStateãcomponentWillMountããŸãã¯renderToStringã®åäœãç°ãªãããã«ããªãããšãæå³ããŸãã
代ããã«ãããã§èª¬æããåé¡ã解決ããããã«æ°ããé¢æ°ãè¿œå ããå¿ èŠããããŸãã ã¯ã©ã€ã¢ã³ãã§ã®ã¿åŒã³åºãããé¢æ°ãããã®ãšåãããã«ããµãŒããŒã§ã®ã¿åŒã³åºãããé¢æ°ãååšããå¯èœæ§ããããŸãã
ãrenderToStringAsyncãé¢æ°ãreact-dom / serverã«è¿œå ã§ãããšæããŸãã éåžžã®renderToStringãšã®éãã¯ãPromiseãè¿ãããšã§ãã
å®è£ åŽã§ã®å¯äžã®éãã¯ãéåæããŒãžã§ã³ã¯ãComponentã€ã³ã¹ã¿ã³ã¹ãäœæãããã³ã«ãrenderïŒïŒãåŒã³åºãåã«ãæåã«ãinitializeïŒïŒããåŒã³åºããŠåŸ æ©ããããšã§ãã ã³ã³ããŒãã³ãã«ãåæåãã¡ãœããããªãå Žåã¯ãrenderïŒïŒãããã«åŒã³åºãããšãã§ããŸãã
ãããã£ãŠã次ã®äŸã®ã¢ããªæ§é ãããå ŽåïŒ
ComponentB
ComponentC
ComponentD
ComponentE
ããã»ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
1) instanciate componentA
2) await componentA.initialize();
3) componentA.render()
4) do in parallel(
instanciate componentB, await componentB.initialize(), componentB.render()
instanciate componentC, await componentC.initialize(), componentC.render(), do in parallel(
instanciate componentD, await componentD.initialize(), componentD.render()
instanciate componentE, await componentE.initialize(), componentE.render()
)
)
5) render to string
ãããã£ãŠãåºæ¬çã«ã¯ãæ°ãããªãã·ã§ã³ã®é¢æ°ãinitializeãã䜿çšããæ°ããé¢æ°ãrenderToStringAsyncããå¿ èŠã§ãã ããã»ã©é£ããããšã§ã¯ãªãã§ãããã
@VanCodingã¯ãç§ããã°ããèããŠããã®ãšåãèããæã£ãŠããŸãã ã¯ã©ã€ã¢ã³ãã®componentDidMountã§initializeãèªåçã«åŒã³åºãããšãã§ãããã©ããçåã«æã£ãŠããŸãããïŒ
ãããã£ãŠããµãŒããŒã§ã¯æ¬¡ã®ããã«ãªããŸãã
initialize()
render()
ãããŠãã¯ã©ã€ã¢ã³ãã§ã¯æ¬¡ã®ããã«ãªããŸãã
render() // without data (unless available synchronously)
componentDidMount()
initialize()
render() // with data
ç§ã¯react-routerv4ã䜿çšããreactserverã¬ã³ããªã³ã°ãšãGraphQLã䜿çšããreact-apolloã®å®çšçãªå®è£ ãæã£ãŠããŸãã
ããã¯ã server-side-rendering-code-splitting-and-hot-reloading-with-react-routerã«è§ŠçºãããŸããã
åºæ¬çã«ããµãŒããŒã¬ã³ããªã³ã°ã¯åæã³ã³ããŒãã³ãã䜿çšããã¯ã©ã€ã¢ã³ãã¬ã³ããªã³ã°ã¯éåæã³ã³ããŒãã³ãã䜿çšãããããwebpackã¯ã¢ãžã¥ãŒã«javascriptãéåæã§ããŒãããã³å®è¡ããŸãã
ã¡ãªã¿ã«ããµãŒããŒã®ã¬ã³ããªã³ã°ã¯Nashorn Script EngineïŒJVMïŒã§å®è£ ãããŠããŸãã
ã¯ã©ã€ã¢ã³ãã¬ã³ããªã³ã°ã³ãŒã
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/src/main.js#L63 -L82
ãµãŒããŒã¬ã³ããªã³ã°ã³ãŒã
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/src/main.js#L128 -L155
ã«ãŒãå
ã®åæã³ã³ããŒãã³ããŸãã¯éåæã³ã³ããŒãã³ããåºå¥ããããã®éèŠãªå Žæã1ã€ãããŸãã
ã«ãŒãå
ã®åæãããã³ã³ããŒãã³ã
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/src/routes/Counter/Route.js#L10
RouteAsyncã®éåæã³ã³ããŒãã³ã
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/src/routes/Counter/RouteAsync.js#L7 -L23
泚ïŒãã¡ã€ã«åã¯Route.jsãŸãã¯RouteAsync.jsã§ããå¿
èŠããããŸãã ã³ãŒãã¯åžžã«RouteAsync.jsãã€ã³ããŒãããå¿
èŠããããŸãã ãµãŒããŒã¬ã³ããªã³ã°çšã«æ§ç¯ãããŠããå ŽåãWebpackã¯Route.jsã«çœ®ãæããŸãã
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/build/webpack.config.js#L72 -L80
ãããã£ãŠããã«ãdist
ãšdist_ssr
2ã€ã®ããŒãžã§ã³ãããã dist
ã¯ã¯ã©ã€ã¢ã³ãçšã§ã dist_ssr
ã¯ãã³ããŒãšã¢ããªã®2ã€ã®ãã£ã³ã¯ãããªããµãŒããŒçšã§ãã ã ã¹ãã¢ã®ç¶æ
ããšã¯ã¹ããŒããããindex.htmlã®<script>
ã«__INITIAL_STATE__
ãšããŠåã蟌ãŸããŸãã ãã«ãã®2ã€ã®ããŒãžã§ã³ãããçç±ã¯ã ReactDomServer.renderToString()
ããŸã éåæã³ã³ããŒãã³ãããµããŒãããŠããªãããã§ãã
two-versions-buildã¢ãããŒãã®å¯äžã®åé¡ã¯ãéçºã¢ãŒãã§èŠåãçºçããããšã§ãã
React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
ãã ããã¯ã©ã€ã¢ã³ããšãµãŒããŒã®ããŒãžã§ã³ã®éãã¯Route.jsãšRouteAsync.jsã®ã¿ã§ãããããèŠåã¯ç¡èŠã§ããŸããèŠåã¯æ¬çªã¢ãŒãã§ã¯è¡šç€ºãããŸããã
ãµãŒããŒåŽã§ã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããåã«éåæããŒã¿ããã§ããããå ŽåïŒ
const { matchedRoutes, params } = matchRoutesToLocation(rootRoute.routes,
location, [], {}, rootRoute.pattern)
matchedRoutes.filter(route => route.component.loadData).map(route =>
route.component.loadData(store, params))
loadData
ããããŒãããŠå®è¡ããŸãã matchesRoutesã¯ã芪ãã€ã³ããã¯ã¹0
ããã®äžèŽããã«ãŒãã®é
åã§ãã loadData
ã¯ãé çªã«å®è¡ããããšãã䞊è¡ããŠå®è¡ããããšãã§ããŸãã
getDataFromTree
ããreact-apollo/server
ãã¹ãŠGraphQLã¯ãšãªãå®è¡ããŸãããšããã§ãNashorn Script Engineã䜿çšãããšãããã©ãŒãã³ã¹ãæé©åããæ©äŒã1ã€ãããŸãããã³ããŒã«ã¯ãäžåºŠå®è¡ãããŠåå©çšãããã©ã€ãã©ãªã³ãŒããšããªãã£ã«ãå«ãŸããŠãããããåŸã®ãªã¯ãšã¹ãã§ã¯ãã¢ããªãã£ã³ã¯ã®ã¿ãå®è¡ãããŸãã ã©ã€ãã©ãªã¯ãã³ããŒãã£ã³ã¯ã«ç§»åããããããã¢ããªã«ã¯srcã«å°ããjavascriptã³ãŒãã®ã¿ãå«ãŸããŠãããããæ¯åãã³ããŒãã£ã³ã¯ãè©äŸ¡ããå Žåã«æ¯ã¹ãŠããã©ãŒãã³ã¹ãåäžããŸãã ïŒãã¹ãŠã®JavaScriptã¯äžåºŠã³ã³ãã€ã«ãããŠãã£ãã·ã¥ããããªã¯ãšã¹ãããšã«å®è¡ãããŸããïŒ
ã¢ããªã®ãã£ã³ã¯ã«ã¯srcã³ãŒãããå«ãŸããŠããªããšåãã€ããŸããã ãŸãã babel-runtime
ãšã babel-runtime
ã«ãã£ãŠåç
§ãããè€è£œãããcore-js/library
ããŠããŸãã babel-runtime
ã¯ãindex.jsãŸãã¯ã¡ã€ã³ãšã³ããªããªãããããã³ããŒãã£ã³ã¯ã«ç§»åã§ããŸããããã®ãããwebpackã¯ãããã¢ãžã¥ãŒã«ãšããŠèªèã§ããŸããã§ããã ããããã³ãŒããµã€ãºã¯å°ããã§ãã
@VanCodingã®äŸãããã«è©³ããhttps ïŒ
ãã¶ããåæåã¯é©åãªååã§ã¯ãããŸãã-ååã¯ããµãŒããŒäžã§ã®ã¿ããŸãã¯ãã®é¢æ°ãè¿ããããŸã§ã¬ã³ããªã³ã°ãé
延ããç°å¢ã§ã®ã¿äœ¿çšãããããšãæå³ããŠããããšãæ確ã«ããå¿
èŠããããŸã-å¥åãã¯ã©ã€ã¢ã³ãã§ã¯ãããŸããã ã¢ã€ãã¢ïŒ getStaticProps
ã getServerProps
ã getInitialProps
ã getAsyncProps
.. ..
ãŸãããã®ãããªrenderToStringAsyncã¡ãœããã®éçºã«æè¡çãŸãã¯ãã®ä»ã®é害ããããã©ãããã³ã¢ããŒã ããèãã®ãããã§ãããã
@nmaroãããšãé¢æ°ã¯äœãè¿ããªãã¯ããªã®ã§ããgetãã§å§ãŸããªãååããããšæããŸããããããé€ãã°ããããæåã®æ¹æ³ã ãšæããŸãã ç§ã¯ãããæçµçã«ã©ã®ããã«åŒã°ããããæ°ã«ããŸããã
ããã«ãçŽ40è¡ã®ã³ãŒãã§ããã®æŠå¿µå®èšŒãè¡ããŸããã å®çšŒåã§ã®äœ¿çšãç®çãšãããã®ã§ã¯ãããŸããããããŸããŸãªã³ã³ããŒãã³ãã䜿çšãããã¹ãã¯æåããŸããã
ãããã£ãŠãReactããŒã ãããã§ããããæãŸãªãå Žåã¯ããµãŒãããŒãã£ã®ã©ã€ãã©ãªã§ãããè¡ãã®ã¯ããã»ã©é£ãããããŸããã
ãŸãã¯ãrenderToStringã«ãªãã·ã§ã³ãè¿œå ããããšãã§ããŸãã
renderToString(Component, {async: true})
@nmaroããã«ãããé¢æ°ã®æ»ãåãæäŸããããªãã·ã§ã³ã«äŸåããããã«ãªããŸãããããã¯è¯ãç¿æ £ãšã¯èŠãªãããŸããã é¢æ°ã¯åžžã«åãã¿ã€ãã®çµæãè¿ãå¿ èŠããããšæããŸãã
@VanCodingã³ãŒãããµãŒãããŒãã£ã®ã©ã€ãã©ãªãšããŠäœ¿çšããæ¹æ³ã®äŸã¯ãããŸããïŒ
@VanCodingãã£ãããïŒ ãããæ£çŽãªãšããããããreactã®å éšã¬ã³ããªã³ã°ã¢ã«ãŽãªãºã ã«çµ±åããã®ã¯é£ãããšæããŸãã https://github.com/facebook/react/blob/master/src/renderers/dom/stack/server/ReactServerRendering.jsããã§ãã¯ããŠãreactã®å éšã§è¿·åã«ãªããŸã... IMOç§ãã¡ã¯æ¬åœã«èª°ãããã®æèŠãå¿ èŠã§ãè¯ã
@seduboisã¯ãéåžžã®renderToStringé¢æ°ã䜿çšããã®ãšåãããã«é¢æ°ã䜿çšã§ããŸãã ãã ããæååãçŽæ¥è¿ãã®ã§ã¯ãªããæååã«è§£æ±ºãããPromiseãè¿ããŸãã
ãããã£ãŠãããã䜿çšãããšã次ã®ããã«ãªããŸãã
var react = require("react");
var renderAsync = require("react-render-async");
var MyComponent = require("./MyComponent");
renderAsync(react.createElement(MyComponent,{some:"props"}).then(function(html){
console.log(html);
});
çè«çã«ã¯ãéåžžã®renderToStringãšåãæ¹æ³ã§æ¢åã®reactã³ã³ããŒãã³ããã¬ã³ããªã³ã°ã§ããã¯ãã§ãã å¯äžã®éãã¯ãéåæã³ã³ããŒãã³ãããµããŒããããŠããããšã§ãã
@nmaroãã®éãã§ãã ããã¯åœ¹ã«ç«ã¡ãŸãã
ããã®ã¹ããŒã¿ã¹ã¯äœã§ããïŒ
@firasdibç§ãã¡ã¯ãŸã ããã€ãã®åå¿
+1
Googleã®ã€ã³ããã¯ã¹äœæã®åé¡ã«ã¯SSRãå¿ èŠã§ããã以äžã«èª¬æãããã¹ãŠã®æè·ç©ã¯ç§ãã¡ã察åŠããããã®ãã®ã§ããããããã®åé¡ã¯Reactãäžè¬çãªã©ã€ãã©ãªãšããŠæåããããã«éåžžã«éèŠã§ãã
JavaScriptãçŽæãåŸ ã€é©åãªæ¹æ³ãæäŸããŠããã°ãéåæã¬ã³ããªã³ã°å šäœã¯å¿ èŠãªããšæããŸãã 次ã«ã倩æ°ã瀺ããã©ã¡ãŒã¿ãŒãæž¡ãããããŒã¿ã®èªã¿èŸŒã¿ãåæïŒSSRã®å ŽåïŒãŸãã¯éåæïŒå®éã®Webãã©ãŠã¶ãŒã®å ŽåïŒã«ãããã©ãããæå®ã§ããŸãã ããŒã¿èªã¿èŸŒã¿ããžãã¯ã¯ãReactã³ã³ããŒãã³ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§promiseãéå§ããcomponentWillMountã§åŸ æ©ããããšãã§ããŸãã
ããããç§ãç解ããŠããããã«ãReactéçºè ã¯componentWillMountã®æçšæ§ã«çåã瀺ããŠãããã³ã³ã¹ãã©ã¯ã¿ãŒã«ãã¹ãŠã®äœæ¥ãè¡ãããããšãæšå¥šããŠããŸãã ã©ã¡ãã®æ¹æ³ã§ãæ©èœããŸãã
äžéšã®äººã ã¯ãã³ã³ããŒãã³ããçŽç²ãªãã¥ãŒã«ããããšã§åé¡ã«å¯ŸåŠã§ãããšäž»åŒµããŠããŸãã ãããã¯éšåçã«æ£ããã§ãã æ®å¿µãªãããããã¯ãã¬ã³ããªã³ã°ããªãŒãå®äºãããŸã§ããŒãããããŒã¿ãããããªãæãäžè¬çãªã±ãŒã¹ã§ã¯æ©èœããŸããã
åé¡ã®æ žå¿ã¯ãã¬ã³ããªã³ã°é¢æ°ãDOMTreeã«è¿œå ããã³ã³ããŒãã³ããéžæããããžãã¯ãæã€ããšãã§ãããšããããšã§ãã ããããReactãéåžžã«åŒ·åã«ãããµãŒããŒåŽã®ã¬ã³ããªã³ã°ã«éåžžã«é©ããŠããçç±ã§ãã
IMOã®çã®è§£æ±ºçã¯ãçºè¡ããããã¹ãŠã®ããŒã¿èªã¿èŸŒã¿ã®çŽæãreactã«ç»é²ã§ããããã«ããããšã§ãã ãã¹ãŠã®ããŒã¿ã®èªã¿èŸŒã¿ãå®å šãªreactãçŽæãããšãã¬ã³ããªã³ã°çµæã§ã³ãŒã«ããã¯ãããŸãã ããã«ã¯ããã€ãã®æå³ããããŸãã
ãã®çµæãé«éã§ã¯ãªãããã»ã¹ã§ãµãŒããŒåŽã®ã©ã€ãã©ãªãã¯ããã«ãèšç®éçŽçã«ã䜿çšããããšã«ãªããŸãã
ãããã£ãŠãç§ã¯ãŸã ç©äºãæãéããããšãæ¯æããŠäžè¬çãªã±ãŒã¹ã劥åããåé¿çãèããŠããŸã:)
ãããŸã§ã®éãéåæããŒã¿èªã¿èŸŒã¿ç°å¢ã§SSRã解決ããå¿ èŠããããŸãã
ãã®ã¢ãã«ã¯ãç¹å®ã®èšèšã¢ãŒããã¯ãã£ã«é¢é£ä»ããããŠããŸããã ãã©ãã¯ã¹/ reduxã¯ãããã«ã¡ãªãããããããã§ãããã¢ããªã±ãŒã·ã§ã³ã§reduxã¢ãã«ãæŸæ£ãããããããããŸããã
ãã®ã¢ãã«ã®åé¡ã¯ãäžèšã®é ç®1ã§ãã åçŽãªã¢ããªã±ãŒã·ã§ã³ã¯ããã¹ãŠã®ããŒã¿èªã¿èŸŒã¿åŒã³åºããèªèããŠããŸãã ç¬ç«ãããã¢ãžã¥ãŒã«ããåããè€éãªã¢ããªã±ãŒã·ã§ã³ã§ã¯ããã®ã¢ãã«ã«ã¯ãå ã®Reactã³ã³ããŒãã³ãããªãŒã®ããçš®ã®ã¬ããªã±ãŒã·ã§ã³ãããã«ã¯ã¬ã³ããªã³ã°ããžãã¯ãå¿ èŠã§ãã
renderïŒïŒé¢æ°ã§ãã§ã«èšè¿°ãããŠããããžãã¯ãç¹°ãè¿ããã«ãè€éãªãããžã§ã¯ãã§SSRãæ©èœãããæ¹æ³ãããããŸããã ãã©ãã¯ã¹ã¯è§£æ±ºçãããããŸãããã確ãã«ç§ã¯ãããçµéšããŠããŸããã
é ç®1ã®å®è£ ã¯ãããŸãã§ãã react-routerã®äŸã§ã¯ãã«ãŒã¿ãŒãšããŠããã®ã«ãŒãã«å±ããæäžäœã®ã³ã³ããŒãã³ããè¿ãå¿ èŠããããŸãã ãããã®ã³ã³ããŒãã³ããã€ã³ã¹ã¿ã³ã¹åã§ãããšæããŸãã
app.use(function(req, res, next) {
match({ routes, location: req.url }, (error, redirectLocation, renderProps: any) => {
if (error) {
res.status(500).send(error.message)
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search)
} else if (renderProps) {
// You can also check renderProps.components or renderProps.routes for
// your "not found" component or route respectively, and send a 404 as
// below, if you're using a catch-all route.
console.log("renderProps", renderProps)
for (let eachComp of renderProps.components) {
// create an instance of component
// ask component to load its data
// store data loading promise in a collection
console.log("eachComp: ", eachComp)
}
res.status(200).send(renderToString(<RouterContext {...renderProps} />))
} else {
res.status(404).send('Not found')
}
})
});
ãããã£ãŠããããã¬ãã«ã®ã³ã³ããŒãã³ãã¯ãã¯ããçŽç²ãªãã³ã³ããŒãã³ãã§ã¯ãããŸããã ãããã®ã³ã³ããŒãã³ãã¯ãããŒã¿ã®èªã¿èŸŒã¿ãããªã¬ãŒããæ©èœã«ããããããã¬ãã«ã®ã³ã³ãããŒã©ãŒã®åœ¹å²ãæãããŸãã ãã©ãã¯ã¹ã¢ãã«ã¯ãããæ¹åããŸããã ã«ãŒããããŒã¿èªã¿èŸŒã¿æ©èœã®é¢é£ä»ãã«ç§»åããŠãå¥ã®ã¢ãžã¥ãŒã«ã«ç§»åããã ãã§ãã
æ®å¿µãªããããããã³ã³ãããŒã©ãŒã®åã«ãã®æ¹æ³ã§ããŒã¿ãããŒããç¶ãããšãreactã¬ã³ããªã³ã°ã®ç®çã§äœæããããªããžã§ã¯ãã°ã©ããè€è£œãããŸãã ç©äºãåçŽã«ä¿ã€ããã«ïŒå¯èœã§ããã°ïŒããã¹ãŠã®ããŒã¿ã®èªã¿èŸŒã¿ãæäžäœã®ã³ã³ãããŒã©ãŒã¬ãã«ã«é 眮ããå¿ èŠããããŸãã
ãããç§ãèŠãŠãããã®ã§ãã
ãããã®SSRã®åœ±é¿ã«æ°ä»ãããšããããGoogleã®ã€ã³ããã¯ã¹å¯èœãªã¢ããªã±ãŒã·ã§ã³ã«å¯ŸããReactã®æçšæ§ã«ã€ããŠ2床èããããšã§ãããã ããããfluxã¯è§£æ±ºçã§ãããfluxã䜿çšãããšãåçŽãªReactã¢ããªã±ãŒã·ã§ã³ãããã¢ããªã±ãŒã·ã§ã³å šäœãè€éã«ãªããŸãã ç§ã¯ããã«è¡ã£ãããšãããã åçŽãªããŒã¿èªã¿èŸŒã¿æ©èœã®ä»£ããã«ãè€æ°ã®ãã¡ã€ã«ã«ããã£ãŠããžãã¯ã远跡ããå¿ èŠããããŸãã çè«çãªã¬ãã«ã§ã¯ããããžã§ã¯ããå®è¡ãããŸã§ã¯æ¬åœã«è¯ãããã«èŠããŸããã æ°ãã人ã¯å§ããã®ã«èŠåŽããŸããã ã³ãŒãããŒã¹ããreduxãåŒãåºããåŸã¯ããã®ãããªåé¡ã¯ãããŸããã ç§ã¯ããããã¹ãŠã®UIãã¶ã€ã³ã®è€éããžã®çãã ãšæããŸãã:)
ä»é±ã®ReactConfãããReact FiberïŒReact 16ïŒããªãªãŒã¹ãããåŸã圌ãã¯æ¬¡ã®äœæ¥ãèšç»ããŠããŸãïŒReact 17ã®å ŽåãšæãããŸãïŒã
éåæReactã©ã€ããµã€ã¯ã«ã¡ãœãããæ¥ãå¯èœæ§ãããããšãæå³ããŸããïŒ
ããŠããã¡ã€ããŒã¯äž»ã«é«é/ã¹ã ãŒãºãªåã¬ã³ããªã³ã°ã«é¢ãããã®ã§ã¯ãããŸãããïŒ ãµãŒããŒã§ã¯1åã ãã¬ã³ããªã³ã°ããããããããã®å€æŽããµãŒããŒåŽã®ã¬ã³ããªã³ã°ã«åœ±é¿ãäžãããã©ããã¯ããããŸããã
@VanCodingã¯ãå°ãäžæçã ã£ãäžèšã®ã¡ãã»ãŒãžãæŽæ°ããŸããã ç§ã¯ãã¡ã€ããŒããªããªã£ãåŸã®åœŒãã®èšç»ãæå³ããŸããã
ç§ã®ããã«ããã«çéžãã人ã ã®ããã«ãç§ã¯ã圹ç«ã€ãããããªãreactã䜿çšããŠã«ã¹ã¿ã å®è£ ãäœæããããšã«ãªããŸããã
https://github.com/siddharthkp/reaqt
ããŒã¯ããµãŒããŒäžã§ã®ã¿å®è¡ãããasyncComponentWillMountã§ãã ããã§èª¬æããåé¡ãåé¿ããããã«ããã¹ãŠã®ã³ã³ããŒãã³ãã§ã¯ãªãããšã³ããªãã€ã³ãã³ã³ããŒãã³ãã§ã®ã¿äœ¿çšã§ããŸãã
@siddharthkpã³ã³ããŒãã³ããäœã解決ããããšããŠããã®ããå®éã«ã¯ããããŸãããïŒ ãããã¬ãã«ã®ApplicationReactã³ã³ããŒãã³ãã«å¯ŸããŠasyncComponentWillMountã®ã¿ããµããŒãããŠããå Žåããªãã©ã€ãã©ãªã䜿çšããå¿ èŠãããã®ã§ããïŒ ãã®çŽæãå€ã§è§£æ±ºããŠãããrenderãåŒã³åºãããšãã§ããŸããïŒ ãããšãç§ã¯äœããéããŸãããïŒ
@fkrauthan
ãã®çŽæãå€ã§è§£æ±ºããŠãããrenderãåŒã³åºãããšãã§ããŸããïŒ
ããã§ãããŸãã«ãããè¡ãããŠããããšã§ãã
é åã¯ã1ã€ã®ã³ãã³ãã§éåæssrïŒ+ã³ãŒãåå²+ hmrïŒãååŸã§ããããšã§ãã ssrã¯ç°¡åã§ã¯ãªãã®ã§ãå€ãã®äººãssrãå®è£ ããŠããªãã®ãç®ã«ããŸããããããåæ©ã§ããã
ãããã¬ãã«ã®ApplicationReactã³ã³ããŒãã³ãã®asyncComponentWillMountã®ã¿ããµããŒãããŸã
1ã€ã®ã¢ããªã±ãŒã·ã§ã³ã³ã³ããŒãã³ãã§ããå¿ èŠã¯ãããŸããã åããŒãž/ç»é¢/ãšã³ããªãã€ã³ãã®ããŒã¿ãååŸã§ããŸãã ïŒããã§è€æ°ã®ãšã³ããªãã€ã³ãã宣äŒã
ãã®ãã¿ãŒã³ã¯æå³çãªãã®ã§ãããããªãŒå ã®ãã¹ãŠã®ã³ã³ããŒãã³ããç¬èªã®ããŒã¿ãå¿ èŠãšããå Žåãããã©ãŒãã³ã¹ã®æªããã¿ãŒã³ãå©é·ããå¯èœæ§ããããŸãã ãããã¬ãã«ã®ã³ã³ããŒãã³ãã§ããŒã¿ãååŸããå°éå ·ãšããŠåã«æž¡ããšãããŒã¿ãæå¶ãããŸãã
@siddharthkpãªããžããªã¯Next.jsïŒReact Conf BTWã§ãçºè¡šãããŸããïŒãããã©ã®ããã«æ¹åãããŠããŸããïŒ
https://github.com/zeit/next.js
ãšã«ããããµãŒãããŒãã£ã®ã©ã€ãã©ãªã«é¢ããè°è«ã¯IMHOã®ãããã¯ããå€ããŠããŸããç§ãã¡ãèå³ãæã£ãŠããã®ã¯ãReactèªäœã®ãµããŒãã§ãã
ãµãŒãããŒãã£ã©ã€ãã©ãªã«é¢ããè°è«ã¯IMHOã®ãããã¯ããå€ããŠãããç§ãã¡ãé¢å¿ãæã£ãŠããã®ã¯Reactèªäœã®ãµããŒãã§ãã
åæããŸãã reaqtã®åé¡ã§ç¹å®ã®è³ªåã«ã€ããŠè©±ãåãããšãã§ã
ããã®ãŠãŒã¹ã±ãŒã¹ã¯ãreact-nativeããã³react-native-vector-iconsã䜿çšããããšã§ãã ã³ã³ããŒãã³ãã®å°éå ·ã¯ãçŽæããåãåã£ãããŒã¿ã«ãã£ãŠæ±ºå®ãããããã«ããã
const AsyncUser = props => fetchUser()
.then(data => (
<User {...data} />
))
ãµããŒããããŠããå Žåãããã«ããå€ãã®è€éãªã³ãŒããç解ãããããªããæ°ããéåæãã¿ãŒã³ãéãããå¯èœæ§ããããšæããŸãã
åãåé¡ããããŸããssrãå®è¡ããŠãäºæž¬ããããã ãã§ãªããcomponentWillMountã®ã¢ã¯ã·ã§ã³ã«ãã£ãŠãã§ãããããã³ã³ãã³ããæ€çŽ¢ããŸãããããããæºåãããã®ãåŸ ã£ãŠããããããããæååã«ã¬ã³ããªã³ã°ããã«ã¯ã©ãããã°ããã§ããã
誰ããããã䟿å©ã ãšæã£ããã react-frontloadãšããã©ã€ãã©ãªãäœæããŸãããããã䜿çšãããšãpromise-returningé¢æ°ãã³ã³ããŒãã³ãã«ãã€ã³ãããŠããµãŒããŒãšã¯ã©ã€ã¢ã³ãã®äž¡æ¹ã®ã¬ã³ããªã³ã°ã§ã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããããšãã«å®è¡ã§ããŸãã
ãã®é¢æ°ã¯ãµãŒããŒã¬ã³ããªã³ã°ã§ãåæçã«ãå®è¡ãããŸããïŒå®éã«ã¯ããã§ã¯ãããŸãã;-)ãæçµã³ã³ããŒãã³ãã®ã¬ã³ããªã³ã°ã¯è§£æ±ºããããŸã§ãããã¯ãããŸãïŒãã¯ã©ã€ã¢ã³ãã¬ã³ããªã³ã°ã§ã¯éåžžã©ããéåæã«å®è¡ãããããŒãžããµãŒããŒã¬ã³ããªã³ã°ã ã³ã³ããŒãã³ãããšã«ãå®è¡æããããã现ããå¶åŸ¡ããããã«æå®ã§ãããªãã·ã§ã³ããããŸãã
ããã¯ããŒã¿ã®èªã¿èŸŒã¿ã«éåžžã«åœ¹ç«ã¡ãŸã-ç§ã解決ããããã«æžãããŠãŒã¹ã±ãŒã¹ã®ã»ãšãã©ã§ãã ãã£ãŠã¿ãŠïŒ ð
<AsyncComponent
delayRendering={LoadingComponent}
>
{/*return a promise that returns a component here*/}
</AsyncComponent>
ããŒã¿ãããããšãããã£ãŠããã®ã§ãäžèšã®ã¢ãããŒãã§è¡ãå¿ èŠã®ãªããã¹ãŠã®æ¡ä»¶ä»ãã¬ã³ããªã³ã°ã«ã€ããŠèããŠã¿ãŠãã ããã
ããã«åå ããŸãã Reactã«æ¬ ããŠããã®ã¯ãŸã éèŠãªæ©èœã ãšæããŸãã ãŸãããµãŒãããŒãã£ã®ã©ã€ãã©ãªããã®äž»é¡ãã«ããŒããŠããå Žåã§ããããã¯å éšããçŽæ¥è¡ãããå¿ èŠãããããšã«åæããŸãã
ç§ã¯å®è£ ãæãã€ããhttps://github.com/timurtu/react-render-async
éåžžã«åªããéåæã³ã³ããŒãã³ãã€ã³ã¿ãŒãã§ã€ã¹ã@ timurtuã
...ã¿ãªããããã®ã¹ã¬ããã«çŽæ¥é¢ä¿ããããŸããŸãªããšãããã®ã§ãããã§ãã£ã€ã ã鳎ãããããšæã£ãŠããŸããããã®ã¹ã¬ãããé·ãé远跡ããŠããŸããã
babel-plugin-universal-import
+ webpack-flush-chunks ïŒããã³extract-css-chunks-webpack-plugin ïŒã¯ããã®åé¡ãå®éã«è§£æ±ºããããã±ãŒãžã®ãã¡ããªãŒã§ãã ãããŠåããŠã åºæ¬çã«ããµãŒããŒäžã§ã³ã³ããŒãã³ããåæçã«ã¬ã³ããªã³ã°ã§ããŸãããããã«éèŠãªããšã«ãã¯ã©ã€ã¢ã³ãäžã§ã®æåã®åæã¬ã³ããªã³ã°ã®ããã«ãã¬ã³ããªã³ã°ãããæ£ç¢ºãªãã£ã³ã¯ãã¯ã©ã€ã¢ã³ãã«è»¢éããŸãã webpackãã©ã°ã€ã³ãä»ããŠcssãã£ã³ã¯ã¹ã¿ã€ã«ã·ãŒããååŸããããšãã§ããŸãã ããã¯ã @ timurtuãå
±æãããã®ãã main.js
èªã¿èŸŒã¿ã解æãè©äŸ¡ãã¬ã³ããªã³ã°ããããŠæåŸã«æ°ç§åŸã«åçã€ã³ããŒããèŠæ±ããå¿
èŠãããå€ãã®ãã®ãããªã³ã³ããŒãã³ããšã¯ç°ãªããŸãã ãããã¯ãã¹ã¿ã€ã«ãªãã³ã³ãã³ãã®ãã©ãã·ã¥ïŒFOUCïŒã解決ããããã®ãœãªã¥ãŒã·ã§ã³ã§ããããµãŒããŒã«ã¬ã³ããªã³ã°ãããæ£ç¢ºãªãã£ã³ã¯ãããŒãžã«åã蟌ãããšã¯ã§ããŸããã ãŠãããŒãµã«ïŒç§ã®ããã±ãŒãžãã¡ããªãŒã®ååïŒã䜿çšãããšãåŸæ¥ã®Webã¢ããªã®ããã«åäœããåæçãªæ¹æ³ã§ãã€ã³ã¿ã©ã¯ãã£ãïŒTTIïŒççž®ã§ããŸãã ããªãã¯ãã®èšäºã§ããã«ã€ããŠãã£ãšåŠã¶ããšãã§ããŸãïŒ React Universal Component 2.0ïŒbabel-plugin-universal-importã«ãŒãã¬ãã«ãšã³ã³ããŒãã³ãã¬ãã«ã®é·æ/çæã«ã€ããŠã¯è§ŠããŠããŸããããæåã®ãªã³ã¯ã¯äž»ã«ããã«çŠç¹ãåœãŠãŠããŸãã åºæ¬çã«ãããŒã¿ãïŒäžŠåã§ã¯ãªãïŒé çªã«ãã§ããããå¿
èŠããããã¹ããããã³ã³ããŒãã³ããããå Žåãã³ã³ããŒãã³ãã¬ãã«ã¯SSRã«æªåœ±é¿ãåãŒããŸãã ãŸããã«ãŒãããšã«1ã€ã®ãã§ããããæ£ããå®è¡ã§ããªãå Žåã¯ã componentDidMount
ã§è¡ãã®ã§ã¯ãªããããŒã¿ã®äŸåé¢ä¿ãã«ãŒããšã³ãã£ãã£ã«ã¢ã¿ããããŠã³ã³ãã©ã¯ãã圢åŒåããããšããå§ãããŸãã äžèšã®ä»ã®å€ãã®äººããããšåãçµè«ã«éããŸããã Redux-First Routerã¯ãReduxãéåžžã«å¿«é©ã«æäœã§ããããã«ããäžçš®ã®ãå¥çŽãã«æ²¿ã£ãŠããããéåžžã«ããŸã圢åŒåããŠããŸãã
Redux-First Routerã¯ãå€ãã®å€ããã©ãã€ã ãåã³æ°ããããŸãããé©ãã¹ãããšã«ãReduxãšã³ã·ã¹ãã ã«æ¬ ããŠããéšåãšããŠãŽã£ãããšé©åããŸãã Reduxã®ã¯ãŒã¯ãããŒã«ãã€ãã£ããªã«ãŒã¿ãŒãå¿ èŠãªå Žåã¯ãRedux-FirstRouterãè©ŠããŠã¿ãŠãã ããã ããã¯æ¯èŒçæ°ãããç§ã¯ãªãŒãã³ãœãŒã¹ã®åå¿è ã§ãããããã¯ç§ãåºæ¬çã«1幎éåãçµãã§ãããã®ã§ããããããåºãŠãã2ãæã§å€§ããªçœåŒåãåŸãŸããã 人ã ã¯ãããæããŠããŸãã ãã²ãã§ãã¯ããŠã¿ãŠãã ãã:)ã
ãŸããReact Routerãããã¯ããã«åªããReduxã®ãœãªã¥ãŒã·ã§ã³ã§ãããæ®å¿µãªããåªããRedux-LittleRouterãèŠéããŠããæ¹æ³ã§ããžã§ã³ãæ£ããå®çŸããæ¹æ³ã説æããããŒã³ãèšäºããããŸãã
ãã¬ãªãªãŒã¹ïŒRedux-First Router âRedux-Little-Routerãè¶
ããäžæ©
RLRãšRFRã®äž»ãªéãã¯ãRFRãåžžã«LOCATION_CHANGED
ã ãã§ãªããã«ãŒãããšã«ç°ãªãã¢ã¯ã·ã§ã³ã¿ã€ãïŒã€ãŸããURLã®å€æŽïŒããã£ã¹ãããããããšã§ãã ããã«ãããä»ã®ã¢ã¯ã·ã§ã³ãšåæ§ã«ãURLã®å€æŽãã¬ãã¥ãŒãµãŒã®äžæã®ã¿ã€ããšããŠåãæ¿ããããšãã§ããŸãã å°ããèŠãããããããŸãããã倧ããªéãããããŸãã ãã®ããã <Route />
ã³ã³ããŒãã³ãã¯å¿
èŠãããŸãããããã¯ãReduxã©ã³ãã§ã¯äžèŠã§ãã ã«ãŒãthunks
ã§ã®ããŒã¿ãã§ããããReact NativeãReact Navigationãã³ãŒãåå²ãããªãã§ãããªã©ã Redux-FirstRouterããµããŒãããæ©èœã®èšå€§ãªãªã¹ãããããŸãã
人ã ã®èããèãããã§ãã
@faceyspaceyããããšãããããŸããéåæããŒã¿ã«åºã¥ããŠå°éå
·ãèšå®ããå Žåãªã©ãç§ãæ±ããŠããåé¡ã«å¯ŸåŠããŠãããšæããŸããããšãã°ã react-native-vector-icons
ã¯ã¢ã€ã³ã³ãçŽæãšããŠè¿ãããšãã§ããŸãã ããã¯ééããªãå¥ã®èŠæ¹ã§ãããéåæã³ã³ããŒãã³ããç¶æ
ã«çµã³ä»ããcomponentWillMount
ãŸãã¯redux X_GET_START
ã X_GET_END
ãããã³X_GET_ERROR
ã¢ã¯ã·ã§ã³ãã€ã©ãŒãã¬ãŒããåæžããŸããã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããããã«æ¬åœã«ãã®ãªã¯ãšã¹ãã1åã ãè¡ãããå Žåã ããŒã¿ã®ããŒãªã³ã°ãªã©ãè¡ã£ãŠããå Žåã¯ãã¹ããŒããã«ã§reduxã䜿çšããæ¹ãããããçã«ããªã£ãŠããŸã
@faceyspaceyã«ãŒãã¬ãã«ã«ã€ããŠããªããèšã£ãŠããããšã¯ããããŸãããå¿ èŠãªããŒã¿ã®ãã§ããã®ã¿ã«äŸåããåšå²ã®ä»ã®ãã¹ãŠãåæçã«ã¬ã³ããªã³ã°ããå°ããªã³ã³ããŒãã³ãã䜿çšããæ¹ãããã®ã§ã¯ãªãã§ããããã
ããè¯ãïŒ ã©ãïŒ React Nativeã«ã€ããŠïŒ Facebookã®ãããªå€§èŠæš¡ãªçµç¹ã®ReactNativeã¢ããªã§ã¯ïŒ
ãã¶ãReactNativeã§ã ç§ã®èŠè§£ã«SSRãããå Žåãè°è«ã¯ãããŸããã ç¹°ãè¿ããŸããããã§ãããå®è¡ã§ãã1ã€ã®ã³ã³ããŒãã³ãã«å¶éããªãéãããªã¯ãšã¹ãããšã«è€æ°ã®ãã§ããããªããšãããããããšã¯äžå¯èœã§ãã ãã®æç¹ã§ãã«ãŒããšã³ãã£ãã£ãšã®å¥çŽã圢åŒåããããšããå§ãããŸãã
React NativeãšSPAã«ã€ããŠã¯ã確ãã«ã ããããããŒã¿ããããçµã¿èŸŒãŸããŠããã³ã³ããŒãã³ãããã¹ãããã®ã¯é¢åã§ãã Apolloã«ã¯ããã«ããã€ãã®ãã®ããããŸãããæåŸã«ãããŒã¿ãã¢ã®ã³ã³ããŒãã³ããã¹ããæ¬åœã«æ£ãããã€ãŸãã·ãŒã ã¬ã¹ã«ããããã«ãé·ãToDoãªã¹ããããããšã確èªããŸããã ã»ããã¢ãããšã¢ãã¯ãç°¡åãªã¹ãã¢ã1ã€ããã»ããã¢ããã奜ãã§ãã ãã¹ãŠã®ãã¹ãã§ãããè¡ãæ¹æ³ãåå©çšã§ããŸãã 次ã«ãããããã³ã³ããŒãã³ãããã¹ãããã®ã¯ãã¹ãããã·ã§ãããååŸããåçŽãªåæã¬ã³ããªã³ã°ã§ãã ã³ã³ããŒãã³ãã«ããŒã¿ãã£ãããè¿œå ãããšãReactã®ãã¹ãã¯çŽæçã§ã¯ãªããªããŸãã ãããã人ã ã¯ãããè¡ãããããèªååããŸãã æšæºãå°ãªããªããã«ã¹ã¿ã ã¢ãããã¯ã³ãŒãã«è¿ã¥ããŸããã ç§»å ¥ããå¿ èŠã®ããéåæã³ã³ããŒãã³ãããšã«ç°ãªãæŠç¥ãç«ãŠãããããéåžžã«æçœãªæ¹æ³ã§éåæã«ç§»å ¥ã§ããã¹ãã¢ãçšæããæ¹ãçç£æ§ãé«ããªããŸãã
SSRããªãããã¹ãæŠç¥ãã·ãŒã ã¬ã¹ã§éªéã«ãªããªãå Žåã¯ãã³ã³ããŒãã³ãã¬ãã«ã«å察ããŸããã ããªããã¡ã¬ã³ãŒãã§ãããªããããã¯çã«ããªã£ãŠããŸãããªããªãããã¹ãŠã®éçºè ããããã«ãŒãã¬ãã«ã«è§Šããå¿ èŠããªããä»ã®äººã®ããã«ãããå£ãå¯èœæ§ãããããã§ãã ãã®ãããFBã¯RelayãšGraphQLã䜿çšããŠãã®ã«ãŒããéæããŸããã åé¡ã®äºå®ã¯ãäžçã§100瀟ã ããæ¬åœã«ãã®è¹ã«ä¹ã£ãŠãããããªãã®ã§ãã ã§ããããç§ã¯ã³ãã±ãŒã·ã§ã³ãã»ãšãã©ã®äºº/ã¢ããª/äŒæ¥ã«ãšã£ãŠçŸå®ãããèªå€§å®£äŒã ãšèããŠããŸãã ã«ãŒãã¬ãã«ã®ã³ããã€ãã¿ãRedux-First Routerã®ããã«éåžžã«ããŸãæ©èœããããã±ãŒãžãå ¥æãããšãã¡ã³ããŒãã«ãŒãã¬ãã«ã«è§Šããããšãèš±å¯ãããŠããããŒã ã®ã¢ãããŒããéçºããã®ãã¯ããã«ç°¡åã«ãªã
åºæ¬çã«ããããã©ã®ããã«è¡ãããããç解ããããç§ã¯ããªãã®æèŠãèãããã§ãã ããã¯SPAã§ããããšã«æ³šæããŠãã ããã ãããã£ãŠãSSRã®äŸã«ã€ããŠã¯ããã¢ãªããžããªãŸãã¯å®åæã確èªããå¿ èŠããããŸãã ããããããã¯è¯ãã¹ã¿ãŒãã§ãã
æãç°¡åãªæ¹æ³ã¯ãéåæã¬ã³ããªã³ã°ã¡ãœããããµããŒãããããšã ãšæããŸãïŒã¬ã³ããªã³ã°ã¯promiseãè¿ããŸãïŒã ããã«ãããã«ãŒãã³ã³ããŒãã³ããåã³ã³ããŒãã³ãã®ã¬ã³ããªã³ã°ãåŸ æ©ã§ããããã«ãªãããã¡ããã¬ã³ããªã³ã°ã®çµæãçŽæãããŸãã ç§ã¯ããã§preactã«ãã®ãããªãã®ãå®è£ ããŸããhttps://github.com/3axap4eHko/preact-async-example
@faceyspaceyäžèšã®è©³çŽ°ãªåçããããšãããããŸãã ç§ã¯Redux-FirstRouterã®ã¢ã€ãã¢ãæ¬åœã«å¥œãã§ããããã¯ééããªãç§ã®ãã¹ãŠã®åé¡ã解決ãã以åãããã¯ããã«éæã§ã¯ãªãŒã³ãªãã®ã«ãªããŸãã
æ¬åœã«ããããšãïŒ
@raRaRaããªãããããæ°ã«å
¥ã£ãŠãããŠããããã§ãïŒ ...æ倧ã®èª²é¡ã®1ã€ã¯ããããŸã§ã«ãŒãã¬ãã«ã®ããŒã¿ãã§ããã®é©åãªæœè±¡åãè¡ãããŠããªãã£ãããšã§ãã React React v3ã«ã¯ã³ãŒã«ããã¯ããããv4ã«ã¯åªãããã¿ãŒã³ããããŸãïŒç¹ã«react-router-config
ããã±ãŒãžã®å ŽåïŒããv4ã§ã¯èªæã§ã¯ãªãããã¡ãŒã¹ãã¯ã©ã¹ã§ã¯ãããŸããã ããã¯åŸä»ãã§ãã ãã ããããã«éèŠãªã®ã¯ãReduxã«ã¯ååšããªãããšã§ãã ãããã£ãŠãreduxãŠãŒã¶ãŒãå®å
šãªãã«ãŒãã¬ãã«ãã®æœè±¡åãå©çšã§ããããã«ãªã£ãã®ã¯ããããåããŠã§ãã
RFRã§ã¯ããã«ãŒãã¬ãã«ããšãã³ã³ããŒãã³ãã¬ãã«ãã®éèŠæ§ãåèããããšæããŸãã RelayãApolloã®ãããªãã®ã¯ãã³ã³ããŒãã³ããžã®ããŒã¿äŸåé¢ä¿ã®ãã¢ãªã³ã°ã«é¢ããŠå€ãã®èªå€§å®£äŒãçã¿åºããŸããããããã2ã䜿çšããŠããªãå Žåãã©ã€ããµã€ã¯ã«ãã³ãã©ãŒã§äœããè¡ãããšã«ãã£ãŠãããæç¹ã§å·ã€ããäžçã«é¥ãå¯èœæ§ããããŸãã ã
ãšã¯ãããæçµçã«RFRã¯Apolloãšã«ãŒãã¬ãã«ã§çµ±åãããäºå®ã§ãã åè¿°ã®ãŸããªäŸå€ãé€ããŠãã³ã³ããŒãã³ãã¬ãã«ã§ç©äºãè¡ãããšã«ããã¡ãªããã¯ã»ãšãã©ãããŸããã å°ãªããšã80ïŒ ã®æéïŒãããŠããããã¢ããªã§ã¯100ïŒ ïŒãã«ãŒãã«åºã¥ããŠå¿ èŠãªãã¹ãŠã®ããŒã¿ã決å®ã§ããŸãã ãããäžå¯èœãªå Žåã¯ãããã¥ãŒã¬ã€ã€ãŒãã§ããŒã¿ãååŸããŠãããããURLã«ãã£ãŠãã¹ãŠã解éãããããã«åèãããå¯èœæ§ããããŸãã ãã®ãããApolloã®ãããªããŒã«ã䜿çšããŠããåé¡ã®ããã¢ã³ããã¿ãŒã³ã«åãçµã¿å§ããŸããããã«ããããç¶æ ãããã¥ãŒã¬ã€ã€ãŒä»¥å€ã®å Žæã«é 眮ããªãããšã§ãæçµçã«ã¯çã¿ãåŒãèµ·ããå¯èœæ§ããããŸãã ã€ãŸãããããã®ããŒã¿ãã§ãããå®è¡ããããã«å¿ èŠãªç¶æ ã§ãã å€ãã®å ŽåãããŒã¿ã®ãã§ããã«äœ¿çšãããæ£ç¢ºãªãã©ã¡ãŒã¿ãŒã調æŽããå¿ èŠããããŸãã ãããã£ãŠãããŒã¿ããã§ããããçŽåã«ãç¶æ ãšå°éå ·ãååŸãã2ãå€æããŠãã©ã¡ãŒã¿ãååŸããŸãã ããã¯ãçŸåšãã¥ãŒã¬ã€ã€ãŒã«ååšãããã®åã¬ã³ããªã³ã°ã¡ã«ããºã ïŒã€ãŸããã©ã€ããµã€ã¯ã«ãã³ãã©ãŒãåŒã³åºããããšãïŒã®å¯Ÿè±¡ãšãªããã®ã§ãã ããæç¹ãŸãã¯å¥ã®æç¹ã§ã®ãã¹ãŠã®ã¢ããªã¯ãåä¿¡/å€æŽãããç¡é¢ä¿ã®å°éå ·ã«å¿ããŠãããŒã¿ããã§ãããããã¹ããšãã«ãã§ãããããªãããŸãã¯ãã§ãããããªããšããçµæã«ãªããŸãã ãŸãããã¹ãŠã®ã¢ããªã§ãå€æŽãããç¡é¢ä¿ã®å°éå ·ãé²ãããã«è¿œå ã®ã³ãŒããäœæããå¿ èŠããããŸãã ã€ãŸããããŒã¿ã®ãã§ããã«äœ¿çšããããã©ã¡ãŒã¿ã«åœ±é¿ãäžããªãå°éå ·ã
React Native + Apolloã®å ŽåãSSRããªãããããµãŒããŒã§é 次ããŒã¿ãã§ãããçºçããå¯èœæ§ããããããåé¡ã¯å°ãªããªããŸãã ãã ããç»é¢ãéåžžã«å°ããå Žåãã³ã³ããŒãã³ãã¬ãã«ã®ããŒã¿ãã§ãããæ¬åœã«å¿
èŠã§ããã ããªãã¯äžè¬çã«ãããããã®ãã·ãŒã³ãããã®ããŒã¿ã«é¢ããŠäœãå¿
èŠãšããŠããããç¥ã£ãŠããŸãã ããã¯ã100äžåã®ã°ã©ããè€æ°ã®ããŒãã«ãªã©ãåãããã¹ã¯ãããWebããã«ããã·ã¥ããŒãã®ãããªãã®ã§ã¯ãããŸããããã®1ã€ã®ãŠãŒã¹ã±ãŒã¹ã¯ãã³ã³ããŒãã³ãã¬ãã«ãæå³ããªãå§ããæ倧ã®äž»èŠãªå Žæã§ãã ãã ããããã§ããããããã¹ãŠã®ãŠã£ãžã§ããã®ãã¹ãŠã®èŠä»¶ã1ã€ã®å Žæã§æå®ããApolloãä»ããŠãããããã§ããã§ããŸãã ãŸã ååã«èããŠããŸããããåºæ¬çãªèãæ¹ã¯ãGraphQLããŒã¿èŠä»¶ãã«ãŒãã«ã¢ã¿ããããŠãããä»ã®ReduxããŒã¿ãšåãããã«ã³ã³ããŒãã³ãã§ããŒã¿ã«æ¥ç¶ããããšã§ãã ã€ãŸããããå
·äœçã«ã¯ãreact-reduxã®connect
ãšApolloã®åçã®ãã®ã®äž¡æ¹ãæé€ãããšããèãæ¹ã§ãã 1ã€ã ã欲ããã®ã§ããããã£ãšãã©ããã«ãããã®ã§ãã Apolloã䜿çšããã«ã¯ãã³ã³ããŒãã³ãã«æ¬åœã«å¿
èŠãªãã®ã«ã¢ã¯ã»ã¹ããããã«ãããæ·±ããã¹ããããããŒã¿ãç Žæ£ããå¿
èŠããããŸãã ããžã§ã³ã¯ãéåžžã®Reduxãšåãããã«èŠãã1ã€ã®æ¹æ³ã«å ããŠãã«ãŒãã¬ãã«ã§ã®graphqlä»æ§ã§ãã
ç§ã¯ã»ãšãã©èª¿ã¹ãŠããªãã®ã§ãããã«ã€ããŠè©±ãã®ã¯å°ãææå°æ©ã§ãããã«ãŒãã¬ãã«ãã¢ããªã®æ£ããã¢ãããŒãã§ããå ŽåãApollo + GraphQLãäŸå€ã§ã¯ãããŸããã
æåŸã«ããã¹ãŠã®ããŒã¿äŸåæ§ãšéåæäœæ¥ãã³ã³ããŒãã³ãããåé¢ãããŠããå Žåããã¹ãã¯éåžžã«ç°¡åã§ãã é¢å¿ã®åé¢ã¯ãããŒã¿ãã§ããã«ã€ããŠå¿é
ããããšãªãã³ã³ããŒãã³ãããã¹ãã§ããå Žåãçç£æ§ã倧å¹
ã«åäžãããŸãã ãã¡ããããã¹ãã§ã¯ãäºåã«éåæãã§ãããå®è¡ããŠã¹ãã¢ã«ããŒã¿ãå
¥åããå¿
èŠããããŸãããã³ã³ããŒãã³ãããåé¢ããŠãããšããã¹ãŠã®ãã¹ãã§äºåã«äœ¿çšããããã€ãã®setup
ãã«ããŒé¢æ°ã®äžã§ãã®ãããªäœæ¥ãç°¡åã«åœ¢åŒåã§ããŸããã³ã³ããŒãã³ããã©ã®ããã«ã¬ã³ããªã³ã°ããããããã¹ãããåã«ãã¹ãã¢ã«ããŒã¿ãå
¥åããŸã:)
@faceyspaceyç§ã¯å®å šã«åæããŸãã ããããç§ã¯ApolloãGraphQLãè©Šããããšããªãããšãèªããªããã°ãªããŸãããç§ã¯ãããã確å®ã«ãã§ãã¯ããŠãããããç§ã®ãŠãŒã¹ã±ãŒã¹ã«ã©ã®ããã«é©åãããã確èªããŸãã
ç§ã¯MVCãã¿ãŒã³ã䜿çšããŠWebã¢ããªã±ãŒã·ã§ã³ãäœæããããšã«éåžžã«æ £ããŠããŸããããã§ã¯ãåºæ¬çã«ãã¹ãŠã®ããŒã¿ãšã³ã³ãããŒã©ãŒãžã®äŸåé¢ä¿ãååŸããŸãã 次ã«ãããŒã¿ããã¥ãŒãŸãã¯ããžãã¹ããžãã¯ã«æ¿å ¥ããŸãã ããªããèšã£ãããã«ãããã¯ãã¥ãŒãããŒã¿ãã§ãããšçµåãããŠããªãã®ã§ãã¹ããã¯ããã«ç°¡åã«ããŸãã
ãã¥ãŒéšåãããŒã¿ããã§ããããŠããžãã¹ããžãã¯ãå®è¡ããŠããMVCã¢ããªã±ãŒã·ã§ã³ãèŠãããšããããŸãããããã¯ã²ã©ããã®ã§ãã äžéšã®ãã¥ãŒ/ã³ã³ããŒãã³ãã«é ãããŠããããã¹ããå°é£/äžå¯èœã«ãªããããã©ã¡ãã®ããŒã¿ããã§ããããããããããŸããã
ç§ã«ãšã£ãŠãRedux-First Routerã¯ãMVCã®ã³ã³ãããŒã©ãŒéšåãšã«ãŒãã«éåžžã«ãã䌌ãŠããŸãã ããã¯ãšãŠãçã«ããªã£ãŠããŸã:)
ããããšãã
çµå±ã®ãšãããæ°ããã¹ã¿ãã¯ã¯æ¬¡ã®ãšããã§ãã
MïŒãªããã¯ã¹
VïŒåå¿ãã
CïŒ Redux-æåã®ã«ãŒã¿ãŒïŒãŸããªããRudyãã«ååãå€æŽãããŸãïŒ
ReactïŒç¹ã«ReduxïŒãç»å Žãããšããç§ãã¡ã¯çãMVCã®å€ä»£ã®ç¥æµãæšãŠãããšæã£ãŠããããã§ããããŸãã§ã以åã®ã¢ããªã±ãŒã·ã§ã³ãéçºããéã®èŠçãå®å šã«åãé€ãããšãã§ãããã®ããã§ããã ããããæçµçã«ã¯ãããããµããŒãããããã®ããŒã«ããŸã æ§ç¯ãããŠããªãã ãã ãšæããŸãã çµå±ã®ãšããããªã¢ã¯ãã£ããªã¯ã©ã€ã¢ã³ããã¡ãŒã¹ãã®ã¢ããªã±ãŒã·ã§ã³ã§ãã£ãŠããMVCã®æ©æµã倧ãã«åããŠããŸãã
æ°ããã¯ã©ã€ã¢ã³ããã¡ãŒã¹ãã¹ã¿ãã¯ãšåŸæ¥ã®ãµãŒããŒãµã€ãMVCã§ã¯åäœãå°ãç°ãªãå ŽåããããŸãããåºæ¬çã«ã¯åã3ã€ã®é¢å¿ã®åé¢ã§ãã
3ã€ã®çžäºäœçš/åäœã®éãã«ã€ããŠã¯ãåºæ¬çã«ããããŸã§ã³ã³ãããŒã©ãŒã¯åæ段éã§ã¢ãã«ãååŸãããããã䜿çšããŠãã¥ãŒãã¬ã³ããªã³ã°ããŠããŸããã ãããŠä»ã§ã¯ãã³ã³ãããŒã©ãŒïŒRFRïŒãããã«ãã¥ãŒãã¬ã³ããªã³ã°ãïŒãUIã¢ãã«ããã€ãŸãReduxç¶æ ã§éžæïŒãã³ã³ãããŒã©ãŒããã¡ã€ã³ã¢ãã«ïŒãããReduxç¶æ ã§ä¿åãããŠããïŒãèŠã€ãããããã¥ãŒãããäžåºŠ
ããã«ã¡ã¯ã¿ããªããã®ãªã³ã¯ãèŠãŠãã ããã ãããããŒã¿ãµãŒããŒåŽã®ã¬ã³ããªã³ã°äŸã§ãhttps://github.com/bananaoomarang/isomorphic-redux
@ harut55555 idkããã¯ç§ã ããããããŸããããããã¯getãªã¯ãšã¹ããšpostãªã¯ãšã¹ããè¡ãããã®å€ãã®ã³ãŒãã®ããã§ã
äœãå€æŽã¯ãããŸããïŒ ãªãªãŒã¹ããã16ã®åå¿ãšã»ãšãã©ã®ãœãªã¥ãŒã·ã§ã³ãæ©èœããªã
çŸåšã®ã¢ãããŒãã¯ãreduxobservableãreduxthunkãªã©ã®ããŒã«ã§reduxã䜿çšããããšã ãšæããŸã
ç§ã®äœ¿çšäŸ
<App>
<Page>
<AsyncModule hre="different.com/Button.react.js" /> downloaded from external url on server or client
</Page>
</App>
åé¡ã¯ãã¢ããªãã¬ã³ããªã³ã°ããåã«ãã©ã®ãããªã³ã³ããŒãã³ãã䜿çšãããããããªãããšã§ãã
奜å¥å¿æºçãªã³ã³ããŒãã³ãã§ã¯ãªããããŒã¿/ã³ã³ãã³ããããŠã³ããŒãããŠã¿ãŸãããïŒ
ãã€ïŒ åçããŒãžããããã³ã³ããŒãã³ãã¯ããã§ããå Žåãšããã§ãªãå ŽåããããŸã
æ¡ä»¶ä»ãã¬ã³ããªã³ã°ãå¿ èŠãªããã§ãhttps://reactjs.org/docs/conditional-rendering.html
ã«ãŒãã£ã³ã°ã®åé¡ã ãšæããŸããreactã¯ããŒãžãã¬ã³ããªã³ã°ããã ãã§ãã¬ã³ããªã³ã°ããŒã¿ã管çããã³èŠæ±ããã¹ãã§ã¯ãããŸããã
Apolloã®@graphql
ã䜿çšãããšãããŒã¿ã®èªã¿èŸŒã¿ãéåžžã«ç°¡åã«ãªããReact-Router v4ã³ã³ããŒãã³ãããŒã¹ã®APIã䜿çšãããšãã·ã³ãã«ãªã³ã³ããŒã¶ãã«ã«ãŒãã£ã³ã°ãå¯èœã«ãªããŸãã ã©ã¡ããReduxã®ã¢ããªã±ãŒã·ã§ã³ç¶æ
ã«çŽäº€ããŠããŸãã
ããŒã¿ã®ãã§ãããåŸ
æ©ããã·ã³ã°ã«ãã¹ã¹ããªãŒãã³ã°ã¬ã³ããªã³ã°ãå®è¡ããã«ã¯ã render()
ãpromiseãè¿ãããšãã§ããå¿
èŠããããŸãïŒã¯ã©ã€ã¢ã³ãã§ã¯ãä»ãšåãããã«ããµãŒããŒã§ã®ã¿promiseãè¿ããŸãïŒã
次ã«ã @graphql
ã¯ãããŒã¿ãããŒããããåŸãrenderïŒïŒã®promiseãè¿ãããšãã§ããŸãã æ®ãã¯ãã¹ãŠåçŽãªReactã§ãã
æ°ã¶æåãç§ã¯JSConfã¢ã€ã¹ã©ã³ãã§ãReactã®ä»åŸã®éåæã¬ã³ããªã³ã°æ©èœã«ã€ããŠèª¬æããŸããïŒç¬¬2éšãåç §ïŒïŒ https ïŒ//reactjs.org/blog/2018/03/01/sneak-peek-beyond-react
@acdliteã¯ãåãæŠå¿µãé©çšããŠãReactã³ã³ããŒãã³ãã§ãµãŒããŒäžã®ããŒã¿ãéåæçã«åŸ æ©ããæºåãã§ãããããŒã¯ã¢ããã段éçã«ãã©ãã·ã¥ããæ¹æ³ã«ã€ããŠèª¬æããŸããïŒ https ïŒ
ãããã®è¬æŒãã楜ãã¿ãã ããã 1幎ããããã§ãã®åé¡ãçµããããããã«å¯Ÿããå ¬åŒã®æŠç¥ãç«ãŠãããšãã§ãããããããªããšæããŸãã
ãªã³ã°ãèŠããŠããŸãã ç§ãã¡ã¯çµå©ããŠæªæ¥ãäžç·ã«èšç»ããŠããŸãã ä»ãããçµããããŠãç§ã«äŒãã«æ¥ãŠãã ããã åãæéã¯ãã€ãæ
ReactDOMServer.renderToStaticMarkup
ã䜿çšããŠããªãŒããŠã©ãŒã¯ããéåæã®äŸåé¢ä¿ã«å°éããå Žæã«ããã¯ããŒã¯ãé
眮ãïŒéåžžãAPIããããŒã¿ãããŒãïŒãããªãŒå
šäœã解決ããããŸã§ããããã®äŸåé¢ä¿ã解決ããããŸã§ããªãŒããŠã©ãŒã¯ãç¶ããããšãã§ããŸãã次ã«ãæåŸã®ReactDOMServer.renderToString
ãå®è¡ããŠãå®éã«HTMLã«ã¬ã³ããªã³ã°ããŸããããã¯ããã¹ãŠã®äŸåé¢ä¿ã解決ããããããåæãããŸãã
ç§ã¯react-baconjs
ïŒ render-to-html.jsã§ãã®ã¢ãããŒããæ¡çšã@gaearonã®ã³ã¡ã³ãã«è§ŠçºãããŸããã
@ steve-taylorãããããã¯æ©èœããŸãã ããã¯ã react-frontloadã§äœ¿çšããåé¿çã§ããããŸããããã¯ãReactã¢ããªã§æ©èœãããããã«å¯Ÿããããæ±çšçãªãœãªã¥ãŒã·ã§ã³ã§ãã
åºæ¬çã«ãåæã¬ã³ããªã³ã°ããžãã¯ã2åå®è¡ããæåã®ã¬ã³ããªã³ã°ã§ããããããã¹ãŠã®ããŒã¿èªã¿èŸŒã¿ã®çŽæã解決ãããã®ãåŸ ã£ãŠãã2çªç®ã®ã¬ã³ããªã³ã°ãå®è¡ããããšã§ãéåæã¬ã³ããªã³ã°ãåœé ããŠããã ãã§ãã
æããã«å°ãç¡é§ããããŸãããååã«æ©èœããŸãïŒæåã®ã¬ã³ããªã³ã°ã®åºåã¯åãªãçŽæã§ã¯ãªããå®éã®HTMLã§ããããŸãïŒã çã®éåæãµãŒããŒã¬ã³ããªã³ã°ãReactã«çµã¿èŸŒãŸãããšãé©ãã¹ãããšã«ãªããŸãã
@davnicwilããä»äºïŒ ç¹å®ã®éåæSSRãœãªã¥ãŒã·ã§ã³ãäžè¬åããããšãèããŸããã react-frontloadã¯ç¡å¶éã®éåæ深床ãåŠçããŸããïŒ ããªãããäºåºŠããšèšã£ãã®ã§å°ããã
@ steve-ãã€ã©ãŒä¹Ÿæ¯ïŒ ã¯ããæ·±ãã§ããªãŒå ã®ã³ã³ããŒãã³ãã®æ·±ããæå³ããå Žåãããã¯ç¡å¶éã§ãã ããã«ãããã³ã³ããŒãã³ãèªäœã§ïŒé«éã³ã³ããŒãã³ãã䜿çšããŠïŒããŒã¿èªã¿èŸŒã¿é¢æ°ã宣èšããæåã®ã¬ã³ããªã³ã°ã§ãããçºçãããšãå®è¡ãããŠPromiseãåéãããŸãã
åäœããªãã®ã¯ãããŒã¿ãéåæã§ããŒãããåã³ã³ããŒãã³ããããã«ããããããçã«ããªã£ãŠããå Žåã¯ãçµæã«å¿ããŠåçã«ã¬ã³ããªã³ã°ãããå Žåã§ãã ããã¯ããã®çš®ã®ãã¹ããçºçããªãããã«ã¢ããªãæ§æããå¿ èŠãããããšãæå³ããŸããå®éã«ã¯ãããã¯å€§ããªå¶éã§ã¯ãããŸããã å®éãå€ãã®ç¹ã§ããã¹ããããéåæããžãã¯ã¯ã·ãªã¢ã«ãªã¯ãšã¹ããæå³ããåŸ æ©æéãé·ããªãã®ã«å¯Ÿãããã©ããåã¯ãã©ã¬ã«ãªã¯ãšã¹ããæå³ãããããUXã«é¢ããŠã¯åªããŠããŸãã
ãšã¯ããããã¹ãã®åé¡ïŒå®éã«ã¯ããã®éåæãµãŒããŒã®ã¬ã³ããªã³ã°ã®åé¡å šäœïŒã¯ãè¿ãå°æ¥ãReactã«ç»å ŽããSuspenseã®ãã®ã§è§£æ±ºãããå¯èœæ§ããããŸãã ð€
åèãŸã§ã«ãããã«åãçµã¿å§ããŸããã
https://reactjs.org/blog/2018/11/27/react-16-roadmap.html#suspense -for-server-rendering
çŽ æŽããã@gaearonïŒ
@davnicwil react-baconjs
ã¯ç¡å¶éã®æ·±ãããµããŒãããŸãã
@gaearonããã«ãããcreate-subscriptionã§ãªãã¶ãŒããã«ããµããŒãã§ããããã«ãªãããªãã¶ãŒããã«ã®
ãã®æ©èœã欲ããã®ã¯2ã€ã®çç±ããã§ãã ãŸããç§ã®ã¢ããªã§ã¯ãç¶æ ã¯Webã¯ãŒã«ãŒã«ä¿åãããŸãã ãããã£ãŠãã³ã³ããŒãã³ãã«å¿ èŠãªãã®ç¶æ ã®ããããååŸããããšã¯éåææäœã§ããã5ããªç§ã»ã©ããããããŒã¿ãåŸ ã£ãŠããéã«Reactãäœããã¬ã³ããªã³ã°ããããšã¯æå³ããããŸããã 次ã«ãçŸåšããªãã¶ãŒããã«ãã³ã³ããŒãã³ãã«å€æããæ®éçãªæ¹æ³ã¯ãããŸããããªãã¶ãŒããã«ãæåã®å€ãåæçã«åºåããå Žåã¯ããµãã¹ã¯ã©ã€ãããŠãã®å€ãååŸãããµãã¹ã¯ã©ã€ãã解é€ããŠãããå床ãµãã¹ã¯ã©ã€ãããŠå€æŽããªãã¹ã³ããŸãïŒããããªãã¬ã€ã§ãïŒã create-observableããã¥ã¡ã³ãã®ä»¶åã®äŸïŒã ãŸããæåã®å€ãéåæã§åºåããå Žåã¯ãæåã«nullãã¬ã³ããªã³ã°ããå€æŽããªãã¹ã³ããŸãã
@ steve-taylor react-frontloadã¯ã 1.0.7
ãªãªãŒã¹ã§ãç¡å¶éã®æ·±ãã®ã³ã³ããŒãã³ããã¹ãããµããŒãããããã«ãªããŸããã
ãã®ã©ã€ãã©ãªããã®ã¹ã¬ããã«ãã©ãçãäžéšã®äººã ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸã-ã¯ã©ã€ã¢ã³ã/ãµãŒããŒã¬ã³ããªã³ã°ã§åäœããéåæããŒã¿èªã¿èŸŒã¿ãœãªã¥ãŒã·ã§ã³ãæ¢ããŠããå Žåã¯ãæå°éã®çµ±åäœæ¥ã§ããããã§ãã¯ããå¿ èŠããããŸãã
ã¢ããªãReactHooksã§ãã«ãããããšãã«ãã®åé¡ãçºçããããã解決ããããã«ããã±ãŒãžreact-use-apiãäœæããŸãããããã¯ãAPIããŒã¿ããã§ããããŠSSRããµããŒãããã«ã¹ã¿ã ããã¯ã§ãã ããã±ãŒãžãå°ã£ãŠãã人ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã
ãã ãããŸã å ¬åŒã®è§£æ±ºçãåŸ ã€ããšã楜ãã¿ã«ããŠããŸããreact-frontloadãèšãããã«ãçŸåšã¬ã³ããªã³ã°ãéå§ããããšéåæããŒã¿ã®èªã¿èŸŒã¿ãè¡ãããã®ãåŸ ã€çµã¿èŸŒã¿ã®æ¹æ³ã¯ãããŸããã
æãåèã«ãªãã³ã¡ã³ã
æ°ã¶æåãç§ã¯JSConfã¢ã€ã¹ã©ã³ãã§ãReactã®ä»åŸã®éåæã¬ã³ããªã³ã°æ©èœã«ã€ããŠèª¬æããŸããïŒç¬¬2éšãåç §ïŒïŒ https ïŒ//reactjs.org/blog/2018/03/01/sneak-peek-beyond-react
@acdliteã¯ãåãæŠå¿µãé©çšããŠãReactã³ã³ããŒãã³ãã§ãµãŒããŒäžã®ããŒã¿ãéåæçã«åŸ æ©ããæºåãã§ãããããŒã¯ã¢ããã段éçã«ãã©ãã·ã¥ããæ¹æ³ã«ã€ããŠèª¬æããŸããïŒ https ïŒ
ãããã®è¬æŒãã楜ãã¿ãã ããã 1幎ããããã§ãã®åé¡ãçµããããããã«å¯Ÿããå ¬åŒã®æŠç¥ãç«ãŠãããšãã§ãããããããªããšæããŸãã