
å
¬åŒã®React.jsã©ã€ãã©ãªããã¥ã¡ã³ãã®Advanced Guidesã»ã¯ã·ã§ã³ã®äžé£ã®ç¿»èš³ã®ç¶ç¶ã
Reactã®ããã©ãŒãã³ã¹æé©å
å
éšçã«ãReactã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®æŽæ°ã«å¿
èŠãªã³ã¹ãã®ãããDOMæäœã®æ°ãæå°éã«æããããã€ãã®é«åºŠãªææ³ã䜿çšããŠããŸãã Reactã䜿çšããã»ãšãã©ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãããã©ãŒãã³ã¹ãæé©åããããã®è¿œå æé ãªãã§ãçµæã®ã€ã³ã¿ãŒãã§ã€ã¹ã®é床ã§ååã§ãã ãã ããReactã¢ããªã±ãŒã·ã§ã³ãé«éåããæ¹æ³ã¯ããã€ããããŸãã
æçµïŒçç£ïŒã¢ã»ã³ããªã䜿çšãã
Reactã¢ããªã±ãŒã·ã§ã³ã§ããã©ãŒãã³ã¹ããã¹ãããŠããå ŽåããŸãã¯ããã©ãŒãã³ã¹ã®åé¡ãçºçããŠããå Žåã¯ãçž®å°ãããå®åã¢ã»ã³ããªãŒãå¿
ããã¹ãããŠãã ããã
- Reactã¢ããªã±ãŒã·ã§ã³ãã«ãããã«ãããã«ã¯ã
npm run build
ãnpm run build
ã以äžã®æé ã«åŸãå¿
èŠããããŸãã - åäžãã¡ã€ã«ãã«ãã®å Žåãæ¡åŒµå
.min.js
æçµãã«ãçšã«æºåãããReactããŒãžã§ã³ãæäŸããŸãã - Browserifyã³ã¬ã¯ã¿ãŒã®å Žåã
NODE_ENV=production
ãã©ã¡ãŒã¿ãŒã䜿çšããŠã¢ã»ã³ããªãå®è¡ããå¿
èŠããããŸãã - Webpackãã«ããŒã®å Žåãæçµã¢ã»ã³ããªã®æ§æãã¡ã€ã«ïŒéçšæ§æïŒã«æ¬¡ã®ãã©ã°ã€ã³ãè¿œå ããå¿
èŠããããŸãã
new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('production') } }), new webpack.optimize.UglifyJsPlugin()
éçºçšã¢ã»ã³ããªã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®éçºã«åœ¹ç«ã€è¿œå ã®èŠåãå«ãŸããŠããŸãããè¿œå ã®ã¢ã¯ã·ã§ã³ãå®è¡ããããšã§ã¢ããªã±ãŒã·ã§ã³ã®é床ãäœäžããŸãã
Chromeã®ã¿ã€ã ã©ã€ã³ã䜿çšããã³ã³ããŒãã³ãã®ãããã¡ã€ãªã³ã°
ãµããŒããããŠãããã©ãŠã¶ãŒã®éçºããŒã«ã§ããã©ãŒãã³ã¹ããŒã«ã䜿çšãããšãã³ã³ããŒãã³ãã®ããŠã³ããæŽæ°ãã¢ã³ããŠã³ãã®æ¹æ³ãèŠèŠåã§ããŸãã äŸïŒ

Chromeã§æ¬¡ã®æé ãå®è¡ããŸãã
ã¯ãšãªæååã«?react_perf
ãã©ã¡ãŒã¿ãŒãæå®ããŠã¢ããªã±ãŒã·ã§ã³ãããŠã³ããŒãããŸãïŒäŸïŒ http://localhost:3000/?react_perf
ïŒã
ChromeããããããŒããŒã«ã®[ ã¿ã€ã ã©ã€ã³ ]ã¿ããã¯ãªãã¯ãã[ èšé² ]ãã¯ãªãã¯ããŸãã
ãããã¡ã€ãªã³ã°ããæé ã«åŸããŸãã 20ç§ä»¥äžã¢ã¯ã·ã§ã³ãèšé²ããªãã§ãã ãããããããªããšãChromeãããªãŒãºããå¯èœæ§ããããŸãã
èšé²ãåæ¢ããŸãã
- Reactã€ãã³ãã¯User Timingã©ãã«ã®äžã«ã°ã«ãŒãåãããŸã ã
ãããã®æ°å€ã¯çžå¯Ÿçã§ããããšã«æ³šæããŠãã ããã çç£ã¢ãŒãã§ã¯ã³ã³ããŒãã³ããããéã衚瀺ãããŸã ã æçµçã«ãããã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã誀ã£ãŠæŽæ°ãåä¿¡ããå Žæãããã³ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãæŽæ°ãããæ·±ããšé »åºŠãæ³åããã®ã«åœ¹ç«ã¡ãŸãã
çŸåšãChromeãEdgeãããã³IEã®ã¿ããã®æ©èœããµããŒãããŠããŸããã ãŠãŒã¶ãŒã¿ã€ãã³ã°APIæšæºã䜿çšããŠãããããä»ã®ãã©ãŠã¶ããã®æ©èœã®ãµããŒããè¿œå ããããšãæåŸ
ããŠããŸãã
äžèŠãªåæç»ãé¿ãã
Reactã¯ã衚瀺ããããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®å
éšè¡šçŸãäœæããã³ç¶æããŸãã ã³ã³ããŒãã³ãã«ãã£ãŠè¿ãããReactèŠçŽ ãå«ãŸããŸãã ããã«ãããReactã¯æ¢åã®DOMããŒããäœæããŠå¿
èŠä»¥äžã«ã¢ã¯ã»ã¹ããããšãåé¿ã§ããŸããããã¯ãJavaScriptãªããžã§ã¯ãã䜿çšããæäœãããé
ããªãå¯èœæ§ããããŸãã Native ReactïŒReact NativeïŒãæ©èœããŸããããã®ã¢ãã«ã¯ãä»®æ³DOMããšåŒã°ããããšããããŸãã
ã³ã³ããŒãã³ãã®ããããã£ïŒããããã£ïŒãŸãã¯ç¶æ
ãå€åãããšãReactã¯èŠçŽ ã®æ°ããè¿ãããããŒãžã§ã³ãDOMã«è¡šç€ºããã以åã®ããŒãžã§ã³ãšæ¯èŒããããããåçã§ãªãå ŽåãDOMãæŽæ°ããŸãã
å Žåã«ãã£ãŠã¯ãåãããã³ã°ïŒã¬ã³ããªã³ã°ïŒããã»ã¹ã®éå§åã«åŒã³åºãããshouldComponentUpdate
ã©ã€ããµã€ã¯ã«shouldComponentUpdate
ãªãŒããŒã©ã€ãããããšã«ãããã³ã³ããŒãã³ããé«éåã§ããŸãã ããã©ã«ãã®é¢æ°å®çŸ©ã¯true
è¿ããReactãæŽæ°ã§ããããã«ããŸãã
shouldComponentUpdate(nextProps, nextState) { return true; }
å Žåã«ãã£ãŠã¯ã³ã³ããŒãã³ããæŽæ°ããå¿
èŠããªãããšãããã£ãŠããå Žåã shouldComponentUpdate
é¢æ°ããfalse
ãè¿ããŠãåã¬ã³ããªã³ã°ïŒã¬ã³ããªã³ã°ïŒã®ããã»ã¹ãã¹ãããã§ããŸããããã«ã¯ãçŸåšã®ã³ã³ããŒãã³ãããã³éå±€ã®äžäœã§render()
ã¡ãœãããåŒã³åºãããšãå«ãŸããŸãã
ã¢ã¯ã·ã§ã³ã®shouldComponentUpdate
ãã®å³ã¯ãã³ã³ããŒãã³ãã®ããªãŒã瀺ããŠããŸãã SCU
ã©ãã«ã¯shouldComponentUpdate
é¢æ°ã«ãã£ãŠè¿ãããçµæã衚瀺ãã vDOMEq
ã©ãã«vDOMEq
ReactèŠçŽ ãåã®ãã¥ãŒãšåçãã©ãããvDOMEq
ãŸãã åã®è²ã¯ãã³ã³ããŒãã³ããåæç»ããå¿
èŠãããããšã瀺ããŠããŸãã

C2ã³ã³ããŒãã³ãã§ã¯ã shouldComponentUpdate
é¢æ°ã¯false
è¿ããŸããããã®çµæãC2以äžããå§ãŸããµãããªãŒå
šäœã§ãReactã¯åæç»ããŸããïŒã¬ã³ããŒé¢æ°ãåŒã³åºããŸãïŒããã®ãããC4ããã³C5ã³ã³ããŒãã³ãã§shouldComponentUpdate
é¢æ°ãåŒã³åºãå¿
èŠããããŸããã§ããã
C1ããã³C3ã®true
ã shouldComponentUpdate
ã¯true
è¿ãããããReactã¯äžã«ç§»åããŠåå«ã確èªããå¿
èŠããããŸããã C6ã®å Žåã shouldComponentUpdate
ã¯true
è¿ãã瀺ãããèŠçŽ ã¯ä»®æ³DOMãšåçã§ã¯ãªããããReactã¯DOMãæŽæ°ããå¿
èŠããããŸããã
ããŠãæåŸã®èå³æ·±ããªãã·ã§ã³ã¯C8ã§ãã Reactã¯ã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããå¿
èŠããããŸãããã ReactèŠçŽ ã®æ°ããå
éšè¡šçŸã¯ä»¥åã®ãã®ãšåçã§ãããDOMãæŽæ°ããå¿
èŠã¯ãããŸããã§ããã
Reactã¯C6ã®ã¿ã®DOMãå€æŽããå¿
èŠããããããã¯é¿ããããªãããšã«æ³šæããŠãã ããã C8ã®å Žå-ã¬ã³ããªã³ã°ãããReactèŠçŽ ãæ¯èŒããã®ã«shouldComponentUpdate
ããªãŒãšC7ã³ã³ããŒãã³ãã§ã¯ãèŠçŽ ãæ¯èŒããå¿
èŠãããããŸããã§ããshouldComponentUpdate
ã¯false
ãè¿ãã render
ã¡ãœããã¯åŒã³åºãããŸããã§ããã
äŸ
props.color
ããããã£ãŸãã¯state.count
ç¶æ
state.count
ãšãã«ã®ã¿ã³ã³ããŒãã³ããå€åãããšæ³åããŠãã ããã shouldComponentUpdate
é¢æ°ã§ãããã®ã±ãŒã¹ã®æ€èšŒãå®è£
ã§ããŸãã
class CounterButton extends React.Component { constructor(props) { super(props); this.state = {count: 1}; } shouldComponentUpdate(nextProps, nextState) { if (this.props.color !== nextProps.color) { return true; } if (this.state.count !== nextState.count) { return true; } return false; } render() { return ( <button color={this.props.color} onClick={() => this.setState(state => ({count: state.count + 1}))}> Count: {this.state.count} </button> ); } }
ãã®ã³ãŒãã§ã¯ã shouldComponentUpdate
é¢æ°ã¯props.color
ããããã£ãŸãã¯state.count
ç¶æ
ã®å€æŽããã§ãã¯ããŸãã å€ãå€æŽãããŠããªãå Žåãã³ã³ããŒãã³ãã¯æŽæ°ãããŸããã ã³ã³ããŒãã³ããããè€éãªå Žåã¯ãåæ§ã®ãã³ãã¬ãŒãã䜿çšã§ããŸããã props
ãšç¶æ
ç¶æ
ã®ãã¹ãŠã®ããããã£ïŒãã£ãŒã«ãïŒã®ãè¡šé¢æ¯èŒããå®è¡ããŠãã³ã³ããŒãã³ããæŽæ°ããå¿
èŠããããã©ãããå€æããŸãã ãã®ãã³ãã¬ãŒãã¯éåžžã«é »ç¹ã«äœ¿çšããããããReactã«ã¯ãã®ããžãã¯ãå®è£
ãããã«ããŒããããŸããã³ã³ããŒãã³ããReact.PureComponent
ããç¶æ¿ããã ãReact.PureComponent
ã 次ã®ã³ãŒãã¯ãåã®ãã®ãšåãç®æšãéæããŸãããããã¯æ¬åœã«ç°¡åã§ãïŒ
class CounterButton extends React.PureComponent { constructor(props) { super(props); this.state = {count: 1}; } render() { return ( <button color={this.props.color} onClick={() => this.setState(state => ({count: state.count + 1}))}> Count: {this.state.count} </button> ); } }
ã»ãšãã©ã®å Žåãç¬èªã®shouldComponentUpdate
é¢æ°ãReact.PureComponent
代ããã«ã React.PureComponent
ã䜿çšã§ããŸãã ãã ãã React.PureComponent
ã¯è¡šé¢ã®æ¯èŒã®ã¿ãå®è£
ããè¡šé¢ã®æ¯èŒã§ã¯äžååãªæ¹æ³ã§ããããã£ïŒããããã£ïŒãŸãã¯ç¶æ
ãå€æŽã§ããå ŽåããããŸãããã®ç¶æ³ã¯ãããè€éãªããŒã¿æ§é ã§çºçããå¯èœæ§ããããŸãã ããšãã°ã ListOfWords
ã³ã³ããŒãã³ããå®è£
ããŠãã³ã³ãã§åºåãããåèªã®ãªã¹ãã衚瀺ããå¿
èŠããããšããŸãã芪ã³ã³ããŒãã³ãã®WordAdder
ã¯ããã¿ã³ãã¯ãªãã¯ãããšãªã¹ãã«åèªãè¿œå ããŸãã 次ã®ã³ãŒãã¯æ£ããæ©èœããŸããã
class ListOfWords extends React.PureComponent { render() { return <div>{this.props.words.join(',')}</div>; } } class WordAdder extends React.Component { constructor(props) { super(props); this.state = { words: ['marklar'] }; this.handleClick = this.handleClick.bind(this); } handleClick() {
åé¡ã¯ã PureComponent
ãthis.props.words
é
åã®å€ãå€ãšæ°ããå€ã®åçŽã§æµ
ãæ¯èŒãè¡ãããšã§ãã åçŽãªæ¯èŒã¯ãäž¡æ¹ã®æ¯èŒå€ãåããªããžã§ã¯ãïŒé
åïŒãåç
§ããŠããå Žåã«true
è¿ãtrue
ã handleClick
ã³ã³ããŒãã³ãã®handleClick
ã¡ãœããã®æå®ãããã³ãŒãã¯ã words
é
åãWordAdder
å€æŽããããã handleClick
ã®å€ãå€ãšæ°ããå€ãæ¯èŒãããšãé
åå
ã®åèªèªäœãå€æŽããããšããŠãåçã®å€ãè¿ãããŸãã ListOfWords
ã³ã³ããŒãã³ãListOfWords
æŽæ°ãããŸãããã衚瀺ããå¿
èŠãããæ°ããåèªããããŸãã
äžå€ããŒã¿ã®å
ãã®åé¡ã解決ããæãç°¡åãªæ¹æ³ã¯ãããããã£ïŒpropsïŒãŸãã¯ç¶æ
ã§äœ¿çšããå€ãå€æŽããªãïŒå€æŽããªãïŒããšã§ãã ããšãã°ã concat
ã¡ãœããã䜿çšããŠhandleClick
ã¡ãœãããæžãæããããšãã§ããŸãhandleClick
ã¡ãœããã¯ãæ°ããå€ãè¿œå ããé
åã®æµ
ãã³ããŒãè¿ããŸãã
handleClick() { this.setState(prevState => ({ words: prevState.words.concat(['marklar']) })); }
ES6ã¯é
åã®ã¹ãã¬ããæ§æããµããŒãããŠãããããã³ãŒããããã«ç°¡åã«ãªããŸãã Create React Appã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãäœæããå Žåããã®æ§æã¯ããã©ã«ãã§äœ¿çšå¯èœã§ãã
handleClick() { this.setState(prevState => ({ words: [...prevState.words, 'marklar'], })); };
åæ§ã«ããªããžã§ã¯ãã®å€æŽïŒçªç¶å€ç°ïŒãé¿ããããã«ã³ãŒããæžãçŽãããšãã§ããŸãã ããšãã°ã colormap
ãªããžã§ã¯ããããã colormap
ã®å€ãå€æŽããŠ'blue'
èšå®ããé¢æ°ãäœæãããšããŸãã ééã£ãŠæžããå¯èœæ§ããããŸãã
function updateColorMap(colormap) { colormap.right = 'blue'; }
å
ã®ãªããžã§ã¯ããå€æŽããã«ãããå®è£
ããã«ã¯ã Object.assignã¡ãœããã䜿çšã§ããŸãã
function updateColorMap(colormap) { return Object.assign({}, colormap, {right: 'blue'}); }
updateColorMap
ã¯ãå€ããªããžã§ã¯ããå€æŽããã®ã§ã¯ãªããæ°ãããªããžã§ã¯ããè¿ãããã«ãªããŸããã Object.assign
ã¯ES6ã«å«ãŸããŠãããbabel-polyfillãå«ããå¿
èŠããããŸãã
ES6ã§ã¯ããªããžã§ã¯ãã®ããããã£ãæ¡åŒµããããšãå¯èœã§ãããããçªç¶å€ç°ãèµ·ãããã«ãªããžã§ã¯ãã®æŽæ°ãããã«ç°¡åã«å®è£
ã§ããŸãã
function updateColorMap(colormap) { return {...colormap, right: 'blue'}; }
Create React Appã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãäœæããå Žåã Object.assign
ããã³ãªããžã§ã¯ãã®Object.assign
æ§æã¯ããã©ã«ãã§å©çšå¯èœã§ãã
äžå€ã®ããŒã¿æ§é ã䜿çšãã
Immutable.jsã¯ããã®åé¡ã解決ããå¥ã®æ¹æ³ã§ãã ãã®ã©ã€ãã©ãªã¯ãæ§é 亀æãéããŠæ©èœããäžå€ã§æ°žç¶çãªã³ã¬ã¯ã·ã§ã³ãæäŸããŸãã
- äžå€ ïŒäžåºŠäœæãããã³ã¬ã¯ã·ã§ã³ã¯ãå¥ã®æç¹ã§ã¯å€æŽã§ããŸããã
- æ°žç¶ç ïŒä»¥åã®ã³ã¬ã¯ã·ã§ã³ãšå€æŽãããããŒã¿ã»ããããæ°ããã³ã¬ã¯ã·ã§ã³ãäœæã§ããŸãã å
ã®ã³ã¬ã¯ã·ã§ã³ã¯ãæ°ããã³ã¬ã¯ã·ã§ã³ã®äœæåŸãæå¹ã®ãŸãŸã§ãã
- æ§é ç亀æ ïŒå
ã®ã³ã¬ã¯ã·ã§ã³ãšåãæ§é ãå¯èœãªéã䜿çšããŠæ°ããã³ã¬ã¯ã·ã§ã³ãäœæãããã³ããŒãæå°éã«æããŠããã©ãŒãã³ã¹ãåäžãããŸãã
äžå€æ§ã¯å€æŽã®è¿œè·¡ã容æã«ããŸãã å€æŽã¯åžžã«æ°ãããªããžã§ã¯ãã®äœæã«ã€ãªããããªããžã§ã¯ããžã®ãªã³ã¯ãå€æŽããããã©ããã®ã¿ã確èªã§ããŸãã ããšãã°ããã€ãã£ãJavaScriptã³ãŒãã®å ŽåïŒ
const x = { foo: "bar" }; const y = x; y.foo = "baz"; x === y;
y
ãå€æŽããããšããäºå®ã«ããããããã y
ã¯x
ãšåããªããžã§ã¯ããåç
§ããŸã-ãããã®æ¯èŒã¯true
è¿ãtrue
ã immutable.jsã䜿çšããŠãã®ã³ãŒããæžãæããããšãã§ããŸãã
const SomeRecord = Immutable.Record({ foo: null }); const x = new SomeRecord({ foo: 'bar' }); const y = x.set('foo', 'baz'); x === y;
ãã®å Žåããªããªã x
å€æŽãããæ°ãããªããžã§ã¯ããžã®åç
§ãè¿ãããå Žåã x
ãå€æŽããããšå®å
šã«æ³å®ã§ããŸãã
äžå€ããŒã¿ã®äœ¿çšã«åœ¹ç«ã€ä»ã®2ã€ã®ã©ã€ãã©ãªãŒã¯ã seamless-immutableããã³immutability-helperã§ãã
äžå€ã®ããŒã¿æ§é ã¯ããªããžã§ã¯ãã®å€æŽã远跡ããæãç°¡åãªæ¹æ³ãæäŸããŸããããã¯shouldComponentUpdate
ã䜿çšããå¿
èŠããããã®ã§ãã»ãšãã©ã®å Žåãããã©ãŒãã³ã¹ã倧å¹
ã«åäžããŸãã
åã®ããŒãïŒ
åºå
žïŒ React-äžçŽã¬ã€ã-ããã©ãŒãã³ã¹ã®æé©å