ã¿ãªããããã«ã¡ã¯ïŒ èšäºReact is SlowãReact is FastïŒReact Appsã®æé©åïŒ FrançoisZaninottoã®èšäºã®ç¿»èš³ãå
±æããããšæããŸãã ããã誰ãã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã
èŠçŽïŒ
- åå¿æ§èœæž¬å®
- ãªãæŽæ°ãããã®ã§ããïŒ
- ã³ã³ããŒãã³ãã®æé©å
- shouldComponentUpdate
- åæ§æ
- Redux
- åéžæ
- JSXã®ãªããžã§ã¯ããªãã©ã«ã«æ³šæããŠãã ãã
- ãããã«
åå¿ãé
ããªãå ŽåããããŸãã äžèŠæš¡ã®Reactã¢ããªã±ãŒã·ã§ã³ã¯é
ããªãå¯èœæ§ããããšèšãããã§ãã ãã ãããã®ä»£æ¿åãæ¢ãåã«ãAngularãŸãã¯Emberã®å¹³åçãªã¢ããªã±ãŒã·ã§ã³ãäœéã«ãªãå¯èœæ§ãããããšãç¥ã£ãŠããå¿
èŠããããŸãã
è¯ããã¥ãŒã¹ã¯ãããã©ãŒãã³ã¹ãæ¬åœã«æ°ã«ãããªããReactã¢ããªãæ¬åœã«é«éã«ããã®ã¯ãšãŠãç°¡åã ãšããããšã§ãã ããã«ã€ããŠã¯ãèšäºã®åŸåã§è©³ãã説æããŸãã
åå¿æ§èœæž¬å®
ãé
ãããšã¯ã©ãããæå³ã§ããïŒ äŸãæããŸãããã
material-uiãšReduxã䜿çšããŠãä»»æã®APIã®ç®¡çããã«GUIãæäŸããadmin -on-restãšåŒã°ããåäžã®ãªãŒãã³ãœãŒã¹ãããžã§ã¯ãã«åãçµãã§ããŸãã ãã®ã¢ããªã±ãŒã·ã§ã³ã«ã¯ãããŒãã«å
ã®ã¬ã³ãŒãã®ãªã¹ãã衚瀺ããããŒãžããããŸãã ãŠãŒã¶ãŒã䞊ã¹æ¿ãé åºãå€æŽãããã次ã®ããŒãžã«ç§»åããããåºåããã£ã«ã¿ãŒåŠçããããããšãã€ã³ã¿ãŒãã§ã€ã¹ã®å¿çãæåŸ
ã©ããã«ãªããŸããã
5åã¹ããŒããŠã³ãã次ã®ã¢ãã¡ãŒã·ã§ã³ã¹ã¯ãªãŒã³ãã£ã¹ãã¯ãæŽæ°ã®æ§åã瀺ããŠããŸãã
äœãèµ·ãã£ãŠããã®ããç解ããããã«ãURLã®æåŸã«?react_perf
ãè¿œå ããŸãã ããã«ããã ã³ã³ããŒãã³ããããã¡ã€ãªã³ã°æ©èœãã¢ã¯ãã£ãã«ãªããŸã ãããã¯ãReactããŒãžã§ã³15.4ããå©çšå¯èœã§ãã ãŸããããŒã¿ããŒãã«ãèªã¿èŸŒãŸããã®ãåŸ
ã¡ãŸãã 次ã«ãChromeã®éçºè
ããŒã«ã§[ã¿ã€ã ã©ã€ã³]ã¿ããéãã[èšé²]ãã¿ã³ãã¯ãªãã¯ããŠãããŒãžã®ããŒãã«ã¿ã€ãã«ãã¯ãªãã¯ããŠäžŠã¹æ¿ãé åºãæŽæ°ããŸãã
ããŒã¿ãæŽæ°ããåŸãããäžåºŠèšé²ãã¿ã³ãã¯ãªãã¯ããŠåæ¢ããŸãã Chromeã§ã¯ãããŠãŒã¶ãŒã¿ã€ãã³ã°ãã©ãã«ã®äžã«é»è²ã®ã°ã©ãã衚瀺ãããŸãã
ãã®ãã£ãŒããèŠãããšããªããªããæããããããããŸããããå®éã«ã¯éåžžã«äœ¿ããããã§ãã ãã®ã°ã©ãã¯ãåã³ã³ããŒãã³ãã®å®è¡æéã瀺ããŠããŸãã å
éšã®Reactã³ã³ããŒãã³ãã®æéã¯è¡šç€ºãããªãããïŒãŸã æé©åã§ããŸããïŒãç¬èªã®ã³ãŒãã®æé©åã«éäžã§ããŸãã
ã¿ã€ã ã©ã€ã³ã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®æäœãèšé²ãã段éã衚瀺ãããããŒãã«ããããŒãã¯ãªãã¯ããç¬éãæŠç®ã§ããŸãã
ç§ã®ã¢ããªã±ãŒã·ã§ã³ã¯ããœãŒããã¿ã³ãã¯ãªãã¯ããçŽåŸãRESTãä»ããŠããŒã¿ãåä¿¡ããåã« <List>
ã³ã³ããŒãã³ããåæç»ããããã§ãã 500ããªç§ä»¥äžããããŸãã ã¢ããªã±ãŒã·ã§ã³ã¯ãããŒãã«ããããŒã®äžŠã¹æ¿ãã¢ã€ã³ã³ãæŽæ°ããããŒã¿ã®èªã¿èŸŒã¿ã瀺ãç°è²ã®ç»é¢ã衚瀺ããã ãã§ãã
ã€ãŸããã¢ããªã±ãŒã·ã§ã³ã¯ã¯ãªãã¯ã«å¯Ÿããå¿çãèŠèŠçã«è¡šç€ºããã®ã«500ããªç§ããããŸãã 0.5ç§ã¯éèŠãªææšã§ããUIã®å°é家ã¯ã ãŠãŒã¶ãŒãã¢ããªã±ãŒã·ã§ã³ã®åå¿ã¯100ããªç§æªæºã®å Žåã«ã®ã¿ç¬éçã§ãããšèãããšèšããŸã ã 100 msãè¶
ããã¢ããªã±ãŒã·ã§ã³å¿çã¯ãç§ããé
ãããšåŒãã§ãããã®ã§ãã
ãªãæŽæ°ãããã®ã§ããïŒ
äžã®ã°ã©ãã§ã¯ãå€ãã®å°ããªç©ŽãèŠãããŸãã å€ãã®ã³ã³ããŒãã³ããåæç»ãããããšãæå³ãããããããã¯æªãå
åã§ãã ã°ã©ãã¯ã <Datagrid>
æŽæ°ã«æãæéããããããšã瀺ããŠããŸãã ã¢ããªã±ãŒã·ã§ã³ãæ°ããããŒã¿ãåä¿¡ããåã«ããŒã¿ã§ããŒãã«å
šäœãæŽæ°ããã®ã¯ãªãã§ããïŒ æ£ããããŸãããã
åæç»ã®çç±ãç解ããããšãããšãå€ãã®å Žåã console.log()
ãrender()
é¢æ°ã«è¿œå ããå¿
èŠãããrender()
ã æ©èœã³ã³ããŒãã³ãã®å Žåã次ã®é«æ¬¡ã³ã³ããŒãã³ãïŒHOCïŒã䜿çšã§ããŸãã
ãã³ãïŒ Reactã®æå¹æ§ã®ããã®ãã1ã€ã®ããŒã«ã§ããã æŽæ°ããçç±ã泚ç®ã«å€ããŸã ã ãã®npmããã±ãŒãžã«ãããã³ã³ããŒãã³ããåãå°éå
·ã§åæç»ããããã³ã«ãReactã¯ã³ã³ãœãŒã«ã«èŠåãåºåããŸãã èŠåïŒã³ã³ãœãŒã«ã®åºåã¯éåžžã«è©³çŽ°ã§ãããæ©èœã³ã³ããŒãã³ãã§ã¯æ©èœããŸããã
ãã®äŸã§ã¯ããŠãŒã¶ãŒãåèŠåºããã¯ãªãã¯ãããšãã¢ããªã±ãŒã·ã§ã³ã¯ç¶æ
ãå€æŽããã¢ã¯ã·ã§ã³ãå®è¡ããŸãããªã¹ãã®ãœãŒãé ïŒ currentSort
ïŒãæŽæ°ãããŸãã ãã®ç¶æ
ã®å€æŽã«ããã <List>
ããŒãžã®åæç»ãããªã¬ãŒãããããã«ãã<Datagrid>
ã³ã³ããŒãã³ãå
šäœãåæç»ãããŸãã ãŠãŒã¶ãŒã®ã¢ã¯ã·ã§ã³ãžã®å¿çãšããŠãããŒãã«ã®ã¿ã€ãã«ã«äžŠã¹æ¿ãã¢ã€ã³ã³ã®å€æŽãããã«è¡šç€ºãããŸãã
éåžžãReactã¯1ã€ã®é
ãã³ã³ããŒãã³ãïŒ1ã€ã®å€§ããªç©ŽãšããŠãã£ãŒãã«è¡šç€ºãããŸãïŒã®ããã§ã¯ãªããé
ããªããŸãã ã»ãšãã©ã®å ŽåãReactã¯å€ãã®ã³ã³ããŒãã³ãã®ç¡é§ãªåæç»ã®ããã«é
ããªããŸãã
Reactã®VirtualDOMãéåžžã«é«éã§ããããšãèªãã ãããããŸããã ããã¯äºå®ã§ãããäžèŠæš¡ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãå®å
šãªåæç»ã«æ°çŸã®ã³ã³ããŒãã³ããç°¡åã«å«ããããšãã§ããŸãã æéã®VirtualDOMãã³ãã¬ãŒããšã³ãžã³ã§ããã16ããªç§æªæºã§ãããè¡ãããšã¯ã§ããŸããã
ã³ã³ããŒãã³ãã®æé©å
<Datagrid>
ã³ã³ããŒãã³ãã®render()
ã¡ãœããã¯æ¬¡ã®ãšããã§ãã
ããã¯ã衚圢åŒããŒã¿ã®éåžžã«åçŽãªå®è£
ã®ããã§ãããéåžžã«éå¹ççã§ãã å<DatagridCell>
ã«ãããå°ãªããšã2ã€ãŸãã¯3ã€ã®ã³ã³ããŒãã³ããæç»ãããŸãã èšäºã®åé ã«ããã€ã³ã¿ãŒãã§ãŒã¹ã®ã¢ãã¡ãŒã·ã§ã³ã¹ã¯ãªãŒã³ãã£ã¹ããèŠããšãããããã«ããªã¹ãã«ã¯7åãš11è¡ãå«ãŸããŠããŸããã€ãŸãã7 * 11 * 3 = 231ã³ã³ããŒãã³ããåæç»ãããŸãã currentSort
ã®ã¿ãcurrentSort
ããcurrentSort
ãããããã¯ãã¹ãŠæéã®ç¡é§ã§ãã Reactã¯å®éã®DOMãæŽæ°ããªããšããäºå®ã«ããããããïŒVirtualDOMãå€æŽãããŠããªããšä»®å®ïŒããã¹ãŠã®ã³ã³ããŒãã³ããåŠçããã®ã«çŽ500ããªç§ããããŸãã
ããŒãã«ã®æ¬äœã®ç¡é§ãªåæç»ãé¿ããããã«ãæåã«* æœåº *ããªããã°ãªããŸããïŒ
ããŒãã«ã®æ¬äœããããžãã¯ãæœåºããŠãæ°ãã<DatagridBody>
ã³ã³ããŒãã³ããäœæããŸããã
ããèªäœã§ã¯ãããŒãã«æ¬äœãæœåºããŠãããã©ãŒãã³ã¹ã«åœ±é¿ã¯ãããŸããããæé©åã®æ©äŒãéãããŸãã 倧èŠæš¡ãªæ±çšã³ã³ããŒãã³ãã¯æé©åãå°é£ã§ãã 1ã€ã®ããšã ããæ
åœããå°ããªã³ã³ããŒãã³ãã䜿çšãããšãæ±ãããããªããŸãã
shouldComponentUpdate
Reactã®ããã¥ã¡ã³ãã«ã¯ã shouldComponentUpdate()
ã䜿çšããŠç¡é§ãªåæç»ãåé¿ããæ¹æ³ãéåžžã«æ確ã«èª¬æãããŠããŸãã ããã©ã«ãã§ã¯ãReactã¯åžžã«ã³ã³ããŒãã³ããVirtualDOMã«ãããããŸãã ã€ãŸããéçºè
ãšããŠã®ããªãã®ä»äºã¯ãã³ã³ããŒãã³ãã®å°éå
·ãå€æŽããããã©ããã確èªããå€æŽãããŠããªãå Žåã¯åæç»ãã¹ãããããããšã§ãã
<DatagridBody>
ã³ã³ããŒãã³ãã®å Žåãå°éå
·ãå€æŽããããŸã§åæç»ããªãã§ãã ããã
ãããã£ãŠãã³ã³ããŒãã³ãã¯æ¬¡ã®ããã«ãªããŸãã
import React, { Children, Component } from 'react'; class DatagridBody extends Component { shouldComponentUpdate(nextProps) { return (nextProps.ids !== this.props.ids || nextProps.data !== this.props.data); } render() { const { resource, ids, data, children } = this.props; return ( <tbody> {ids.map(id => ( <tr key={id}> {Children.map(children, (field, index) => <DatagridCell record={data[id]} key={`${id}-${index}`} field={field} resource={resource} /> )} </tr> ))} </tbody> ); } } export default DatagridBody;
ãã³ãïŒ shouldComponentUpdateïŒïŒãæåã§èšè¿°ãã代ããã«ããã®ã¯ã©ã¹ãComponentã§ã¯ãªãPureComponentããç¶æ¿ã§ããŸã ã PureComponentã¯ãå³å¯ãªæ¯èŒïŒ === ïŒã䜿çšããŠãã¹ãŠã®å°éå
·ãæ¯èŒããå°éå
·ãå€æŽãããå Žåã«ã®ã¿åæç»ããŸãã ãããããã®ã³ã³ããã¹ãã§ã¯ãªãœãŒã¹ãšåãå€æŽã§ããªãããšãç¥ã£ãŠããã®ã§ãããããæ¯èŒããå¿
èŠã¯ãããŸããã
ãã®æé©åã«ãããããŒãã«ããããŒãã¯ãªãã¯ããåŸã«<Datagrid>
åæç»ãããšããã®ã³ã³ãã³ããšãã¹ãŠã®231ã³ã³ããŒãã³ããã¹ããããããŸãã ããã«ãããæŽæ°æéã500ããªç§ãã60ããªç§ã«ççž®ãããŸããã ããã¯ã400ããªç§ä»¥äžã®çŽããã©ãŒãã³ã¹ã®åäžã§ãïŒ
ãã³ãïŒãã£ãŒãã®å¹
ã«ã ãŸãããªãã§ãã ãããåã®ãã£ãŒããããããã«è¿äŒŒãããŠããŸãã ããã¯ééããªãåªããŠããŸãïŒ
shouldComponentUpdate
ã¡ãœããã¯ããã£ãŒãã®å€ãã®ç©Žãåé€ããåèšã¬ã³ããªã³ã°æéãççž®ããŸããã åãã¡ãœããã䜿çšããŠãããã«åæç»ãé¿ããããšãã§ããŸãïŒããšãã°ããµã€ãããŒãã¢ã¯ã·ã§ã³ãã¿ã³ãå€æŽãããŠããªãããŒãã«ããããŒãããŒãžããŒã·ã§ã³ãåæç»ããªãã§ãã ããïŒã ããããã¹ãŠã®ããšã§çŽ1æé倧éšãããåŸãåèŠåºããã¯ãªãã¯ãããšãããŒãžå
šäœãããã100ããªç§ã§æç»ãããŸãã ããã¯ååã«é«éã§ã-æé©åãããã®ããŸã ããå Žåã§ãã
shouldComponentUpdate
ã¡ãœããã®è¿œå ã¯é¢åã«æãããããããŸãããã shouldComponentUpdate
ããå Žåã¯ãã»ãšãã©ã®ã³ã³ããŒãã³ãã«å«ããå¿
èŠããããŸãã
ãã ããã§ããéã貌ãä»ããªãã§ãã ãããããªãåçŽãªã³ã³ããŒãã³ãã§shouldComponentUpdate
ãå®è¡ãããšãã¬ã³ããªã³ã°ãé
ããªãããšããããŸãã ã¢ããªã±ãŒã·ã§ã³ã®ã©ã€ããµã€ã¯ã«ã®æ©ã段éã§ãããè¡ããªãã§ãã ããã ãã®ã¡ãœããã¯ãã³ã³ããŒãã³ãã®ããã©ãŒãã³ã¹ã®åé¡ãç¹å®ã§ããå Žåã«ãã¢ããªã±ãŒã·ã§ã³ãæé·ãããšãã«ã®ã¿è¿œå ããŠãã ããã
åæ§æ
<DatagridBody>
ã«å¯Ÿãã以åã®å€æŽã«ã¯ç¹ã«æºè¶³ããŠããŸããshouldComponentUpdate
ãããã·ã³ãã«ã§æ©èœçãªã³ã³ããŒãã³ããã¯ã©ã¹ã«å€æããå¿
èŠããããŸããã ããã«ãããå€ãã®ã³ãŒãè¡ãè¿œå ãããŸããåè¡ã«ã¯ç¬èªã®äŸ¡æ ŒããããŸãïŒäœæããããã°ããµããŒãã®åœ¢åŒïŒã
幞ããªããšã«ã recomposeã®ãããã§shouldComponentUpdate
ããžãã¯ãé«æ¬¡ã³ã³ããŒãã³ãïŒHOCïŒã«å®è£
ã§ããŸã ã ããã¯ãReactã®æ©èœçãªããŒã«ãããã§ãããããšãã°ãHOC pure()
é¢æ°ãæäŸããŸãã
ãã®ã³ãŒããšæåã®å®è£
ã®å¯äžã®éãã¯æåŸã®è¡ã«ãããŸãïŒ pure(DatagridBody)
代ããã«pure(DatagridBody)
ããšã¯ã¹ããŒããDatagridBody
ã pure
ã¯PureComponent
ã«äŒŒãŠãPureComponent
ããè¿œå ã®å®åæã¯ãããŸããã
ç§ã¯ããã«å
·äœçã«ãªãã pure()
代ããã«shouldUpdate()
ã䜿çšããŠå€æŽã§ããããšã確信ããŠããå°éå
·ã«ã®ã¿çŠç¹ãåœãŠãããšãã§ããŸãïŒ
checkPropsChange
ã¯çŽç²ãªé¢æ°ã§ãããåäœãã¹ãçšã«ãšã¯ã¹ããŒãããããšãã§ããŸãã
åæ§æã©ã€ãã©ãªã¯ã onlyUpdateForKeys()
ãªã©ãããå¹ççãªHOCãæäŸãã onlyUpdateForKeys()
ã§è¡ã£ãã®ãšåããã§ãã¯ãå®è¡ãcheckPropsChange
ã
recompose
ã匷ããå§ããrecompose
ã ããã©ãŒãã³ã¹ã®æé©åã«å ããŠãããŒã¿ãµã³ããªã³ã°ããžãã¯ã®æœåºãHOCã®ã³ã³ãã€ã«ãããã³æ©èœçã§ãã¹ãå¯èœãªã¹ã¿ã€ã«ã§ã®å°éå
·ã®æäœãæ¯æŽããŸãã
Redux
Redux ïŒ ããããå§ãããŸã ïŒã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ã®ç¶æ
ãå¶åŸ¡ããå Žåãããã«æ¥ç¶ãããŠããã³ã³ããŒãã³ãã¯æ¢ã«ã¯ãªãŒã³ã§ãã ä»ã®HOCã¯å¿
èŠãããŸããã
1ã€ã®ããããã£ã®ã¿ãå€æŽãããå Žåãæ¥ç¶ãããã³ã³ããŒãã³ããšãã®ãã¹ãŠã®åå«ãåæç»ãããããšãèŠããŠãããŠãã ããã ãããã£ãŠãããŒãžã³ã³ããŒãã³ãã«Reduxã䜿çšããŠããå Žåã¯ãããªãŒã®äžã®ã³ã³ããŒãã³ãã«pure()
ãŸãã¯shouldUpdate()
ã䜿çšããå¿
èŠããããŸãã
ããããReduxã¯å°éå
·ã«å¯ŸããŠå³å¯ãªæ¯èŒã䜿çšããŠããããšãèŠããŠãããŠãã ããã Reduxã¯ç¶æ
ãpropsã³ã³ããŒãã³ãã«ãã€ã³ãããããããªããžã§ã¯ãã®ç¶æ
ãå€æŽãããšãReduxã¯åã«ãããç¡èŠããŸãã ãã®ãããã¬ãã¥ãŒãµãŒã§ã¯äžå€æ§ã䜿çšããå¿
èŠããããŸãã
ããšãã°ãadmin-on-restã§ããŒãã«ã®èŠåºããã¯ãªãã¯ãããšã SET_SORT
ã¢ã¯ã·ã§ã³ããã£ã¹ããããããŸãã ãã®ã¢ã¯ã·ã§ã³ããªãã¹ã³ããReducerã¯ãç¶æ
ã«ãããªããžã§ã¯ãã眮ãæãã æŽæ°ããã¹ãã§ã¯ãããŸããïŒ
ãã®ã¬ãã¥ãŒãµãŒã®ã³ãŒãã«åŸã£ãŠãReduxã¯ããªãã«æ¯èŒã䜿çšããŠå€æŽã®ç¶æ
ããã§ãã¯ãããšãã«ãç¶æ
ãªããžã§ã¯ããå€æŽãããããšãæ€åºããããŒã¿ããŒãã«ãåæç»ããŸãã ãã ããç¶æ
ãå€æŽããå ŽåãReduxã¯ãã®å€æŽãã¹ãããããããã«å¿ããŠäœãåæç»ããŸããã
äžå€ã®ã¬ãã¥ãŒãµãŒãäœæããããã«ãäžéšã®éçºè
ã¯Facebookã®immutable.jsã©ã€ãã©ãªã䜿çšããŠããŸãã ããããES6ã®åæ§ç¯ã«ãããã³ã³ããŒãã³ãããããã£ãéžæçã«çœ®ãæããããšã容æã«ãªã£ãããããã®ã©ã€ãã©ãªã¯å¿
èŠãªããšæããŸãã ããã«ãéãïŒ60 kBïŒã®ã§ããããžã§ã¯ãã«å¿ããŠè¿œå ããåã«ããèããŠãã ããã
åéžæ
Reduxã«æ¥ç¶ãããã³ã³ããŒãã³ãã®äžå¿
èŠãªã¬ã³ããªã³ã°ãé²ãããã«ã mapStateToProps
é¢æ°ãåŒã³åºããããã³ã«æ°ãããªããžã§ã¯ããè¿ããªãããšã確èªããå¿
èŠããããŸãã
ããšãã°ãadmin-on-restã®<List>
ã³ã³ããŒãã³ããåãäžããŸãã 次ã®ã³ãŒãã䜿çšããŠãç¶æ
ããçŸåšã®ãªãœãŒã¹ïŒããšãã°ãæçš¿ãã³ã¡ã³ããªã©ïŒã®ãšã³ããªã®ãªã¹ããååŸããŸãã
ç¶æ
ã«ã¯ããªãœãŒã¹ã«ãã£ãŠã€ã³ããã¯ã¹ãä»ãããã以åã«ããŒãããããã¹ãŠã®ã¬ã³ãŒãã®é
åãå«ãŸããŸãã ããšãã°ã state.admin.posts.data
ã«ã¯æçš¿ã®ãªã¹ããå«ãŸããŸãã
{ 23: { id: 23, title: âHello, Worldâ, }, 45: { id: 45, title: âLorem Ipsumâ, }, 67: { id: 67, title: âSic dolor ametâ, }, }
mapStateToProps
é¢æ°ã¯ãç¶æ
ãªããžã§ã¯ãããã£ã«ã¿ãªã³ã°ããå®éã«ãªã¹ãã«è¡šç€ºãããã¬ã³ãŒãã®ã¿ãè¿ããŸãã ãã®ãããªãã®ïŒ
{ 23: { id: 23, title: âHello, Worldâ, }, 67: { id: 67, title: âSic dolor ametâ, },\ }
åé¡ã¯ã mapStateToProps
é¢æ°ãmapStateToProps
ãããã³ã«ãå
éšãªããžã§ã¯ããå€æŽãããŠããªããŠããæ°ãããªããžã§ã¯ããè¿ãããããšã§ãã çµæãšããŠã <List>
ã³ã³ããŒãã³ãã¯ãäœããç¶æ
ãå€åãããã³ã«åæç»ãããŸããäžæ¹ãæ¥ä»ãŸãã¯IDãå€æŽããå Žåã¯ãidã®ã¿ãå€æŽããå¿
èŠããããŸãã
åéžæã¯ã¡ã¢åã§ãã®åé¡ã解決ããŸãã mapStateToProps
ã§å°éå
·ãçŽæ¥èšç®ãã代ããã«ãreselectã®ã»ã¬ã¯ã¿ãŒã䜿çšããŸããããã¯ãå€æŽãè¡ãããªãã£ãå Žåã«åããªããžã§ã¯ããè¿ããŸãã
import React from 'react'; import { connect } from 'react-redux'; import { createSelector } from 'reselect' const List = (props) => ... const idsSelector = (state, props) => state.admin[props.resource].ids const dataSelector = (state, props) => state.admin[props.resource].data const filteredDataSelector = createSelector( idsSelector, dataSelector (ids, data) => Object.keys(data) .filter(id => ids.includes(id)) .map(id => data[id]) .reduce((data, record) => { data[record.id] = record; return data; }, {}) ) const mapStateToProps = (state, props) => { const resourceState = state.admin[props.resource]; return { ids: idsSelector(state, props), data: filteredDataSelector(state, props), }; }; export default connect(mapStateToProps)(List);
<List>
ã³ã³ããŒãã³ãã¯ãç¶æ
ã®ãµãã»ãããå€æŽããããšãã«ã®ã¿åæç»ãããããã«ãªããŸããã
åæ§æã«é¢ããŠã¯ãã»ã¬ã¯ã¿ãŒã¯ãã¹ããšãã«ããç°¡åãªçŽç²ãªé¢æ°ã§ãã Reduxã«æ¥ç¶ãããŠããã³ã³ããŒãã³ãã®ã»ã¬ã¯ã¿ãŒãäœæããããšããå§ãããŸãã
JSXã®ãªããžã§ã¯ããªãã©ã«ã«æ³šæããŠãã ãã
ããæ¥ãã³ã³ããŒãã³ãã¯ããã«ãã¯ãªãŒã³ãã«ãªããã³ãŒãã«æªããã¿ãŒã³ãèŠã€ãããç¡é§ãªåæç»ã«ã€ãªããå¯èœæ§ããããŸãã ããã®æãäžè¬çãªäŸã¯ãJSXã§ã®ãªããžã§ã¯ããªãã©ã«ã®äœ¿çšã§ããããã¯ãã Notorious {{ ããšåŒã³ãŸãã äŸãæããŸãããã
import React from 'react'; import MyTableComponent from './MyTableComponent'; const Datagrid = (props) => ( <MyTableComponent style={{ marginTop: 10 }}> ... </MyTableComponent> )
<MyTableComponent>
ã³ã³ããŒãã³ãã®style
ããããã£ã¯ã <Datagrid>
ã³ã³ããŒãã³ããæç»ããããã³ã«æ°ããå€ãååŸããŸãã ãããã£ãŠã <MyTableComponent>
ã¯ãªãŒã³ã§ãã£ãŠãã <Datagrid>
åæç»ããã<Datagrid>
åæç»ãããŸãã å®éããªããžã§ã¯ããªãã©ã«ãããããã£ãšããŠåã³ã³ããŒãã³ãã«æž¡ããã³ã«ãçŽåºŠã«éåããŸãã 解決çã¯ç°¡åã§ãã
import React from 'react'; import MyTableComponent from './MyTableComponent'; const tableStyle = { marginTop: 10 }; const Datagrid = (props) => ( <MyTableComponent style={tableStyle}> ... </MyTableComponent> )
ãšãŠãåçŽã«èŠããŸããããã®ãšã©ãŒãäœåºŠãç®ã«ããŠãJSXã§ãæªåé«ã{{
ããçºèŠããæèŠã身ã«ä»ããŸããã å®æçã«å®æ°ã«çœ®ãæããŠããŸãã
次ã«çãããã³ã³ããŒãã³ãã®çé£ã¯React.CloneElement()
ã§ãã ããããã£ã2çªç®ã®ãã©ã¡ãŒã¿ãŒã®å€ãšããŠæž¡ããšãã¯ããŒã³èŠçŽ ã¯ã¬ã³ããªã³ã°ããããã³ã«æ°ããå°éå
·ãåãåããŸãã
äŸãšããŠæ¬¡ã®ã³ãŒãã䜿çšããŠã ãããªã¢ã«UIã§ããã«äœåºŠãç«å·ãè² ããŸããã
import { CardActions } from 'material-ui/Card'; import { CreateButton, RefreshButton } from 'admin-on-rest'; const Toolbar = ({ basePath, refresh }) => ( <CardActions> <CreateButton basePath={basePath} /> <RefreshButton refresh={refresh} /> </CardActions> ); export default Toolbar;
<CreateButton>
ã³ã³ããŒãã³ãã¯ã¯ãªãŒã³ã§ããã <Toolbar>
æç»ããããã³ã«ã¬ã³ããªã³ã°ãããŸãã ããã¯ãmaterial-uiã®<CardAction>
ã³ã³ããŒãã³ãããããŒãžã³ã«é
眮ãããæåã®åã«ç¹å¥ãªã¹ã¿ã€ã«ãè¿œå ãããªããžã§ã¯ããªãã©ã«ã䜿çšããŠãããè¡ãããã§ãã ãããã£ãŠã <CreateButton>
ã¯æ¯åç°ãªãstyle
ãªããžã§ã¯ããååŸããŸãã åæ§æããHOCé¢æ°onlyUpdateForKeys()
ã䜿çšããŠããã解決ããããšãã§ããŸããã
ãããã«
Reactã¢ããªã±ãŒã·ã§ã³ãé«éã«ä¿ã€ããã«å¿
èŠãªããšã¯ä»ã«ããããããããŸãïŒããŒã®äœ¿çšãéãã«ãŒãã®é
延èªã¿èŸŒã¿ã react-addons-perf
addons react-addons-perf
ããã±ãŒãžãServiceWorkersã«ããã¢ããªã±ãŒã·ã§ã³ã®ç¶æ
ã®ãã£ãã·ã¥ãååã®è¿œå ãªã©ïŒããæ£ããå®è£
shouldComponentUpdate
ã¯ãæåã®æãå¹æçãªæé ã§ãã
Reactåç¬ã§ã¯é«éã§ã¯ãããŸãããããããããµã€ãºã®ã¢ããªã±ãŒã·ã§ã³ãé«éã«ããããã®ãã¹ãŠã®ããŒã«ãæäŸããŸãã
ç¹ã«å€ãã®ãã¬ãŒã ã¯ãŒã¯ãReactã«ä»£ãããã®ãæäŸããNåé«éã§ãããšäž»åŒµããå Žåãããã¯çŽæã«åããããã«æãããŸãã ããããReactã¯ããã©ãŒãã³ã¹ã§ã¯ãªããéçºè
ã®äœ¿ãããããšçµéšã«çŠç¹ãåœãŠãŠããŸãã ããããReactã䜿çšãã倧èŠæš¡ãªã¢ããªã±ãŒã·ã§ã³ã®éçºãå¿«é©ãªäœéšã§ãããé©ãããšãªããå®è£
ã®å®å®ããããŒã¹ã§ããçç±ã§ãã
æã
ã¢ããªã±ãŒã·ã§ã³ã®ãããã¡ã€ã«ãäœæããå¿
èŠã«å¿ããŠpure()
åŒã³åºãã®è¿œå ã«æéããããããšãå¿ããªãã§ãã ããã ãã ããæåã¯ãããè¡ããªãã§ãã ããããŸããåã³ã³ããŒãã³ããæé©åããã®ã«æéããããããªãã§ãã ããããã ããã¢ãã€ã«ããã€ã¹ã§è¡ããªãå Žåã¯é€ããŸãã ãŸãããŠãŒã¶ãŒã®èŠ³ç¹ããã¢ããªã±ãŒã·ã§ã³ã®å¿çæ§ã«ã€ããŠè¯ãå°è±¡ãåŸãããã«ãããŸããŸãªããã€ã¹ã§ãã¹ãããããšãå¿ããªãã§ãã ããã
Reactã®ããã©ãŒãã³ã¹ã®æé©åã«ã€ããŠè©³ããç¥ãããå Žåã¯ããã®ãããã¯ã«é¢ããåªããèšäºã®ãªã¹ããã芧ãã ããã