
React.jsã©ã€ãã©ãªã®å
¬åŒããã¥ã¡ã³ããã¥ãŒããªã¢ã«ã®ç¿»èš³ã
Reactãèãã
ç§ãã¡ã®æèŠã§ã¯ãReactã¯JavaScriptã䜿çšããŠå€§èŠæš¡ã§é«éãªWebã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããæè¯ã®æ¹æ³ã§ãã FacebookãšInstagramã§ã®çµéšã§ã¯ãReactã¢ããªãéåžžã«ããŸãæ¡åŒµã§ããŸãã
Reactã®å€ãã®åªããæ©èœã®1ã€ã¯ããã¢ããªã±ãŒã·ã§ã³ãã©ã®ããã«èšèšããäœæãããããšããååã§ãã ãã®ãã¥ãŒããªã¢ã«ã§ã¯ã補åãèŠã€ããããã®ããŒã¿ã®è¡šã衚瀺ããReactã¢ããªã±ãŒã·ã§ã³ãèšèšããã³äœæããæèããã»ã¹å
šäœãå®è¡ããŸãã
ã¬ã€ã¢ãŠãããå§ããŸãããã
ç¹å®ã®JSON APIãšãã¶ã€ããŒããã®ã¬ã€ã¢ãŠãããããšæ³åããŠãã ããã ã¬ã€ã¢ãŠãã¯æ¬¡ã®ãšããã§ãã

JSON APIã¯æ¬¡ã®ãããªããŒã¿ãè¿ããŸãã
[ {category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"}, {category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"}, {category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"}, {category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"}, {category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"}, {category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"} ];
æé 1ïŒãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãã³ã³ããŒãã³ãéå±€ã«ç§»åãã
æåã«è¡ãããšã¯ãã¬ã€ã¢ãŠãäžã®åã³ã³ããŒãã³ãïŒããã³åŸå±ã³ã³ããŒãã³ãïŒã®åšãã«ããã¯ã¹ãæç»ãããããã«ååãä»ããããšã§ãã ããªãããã¶ã€ããŒãšä»äºãããå Žåã圌ã¯ãã§ã«ãããè¡ã£ãŠãããããããªãã®ã§ã圌ãšè©±ãããå¿
èŠããããŸãïŒ Photoshopã®ã¬ã€ã€ãŒåã¯ãReactã³ã³ããŒãã³ãã®åœåã«éåžžã«é©ããŠããããšãå€æããå ŽåããããŸãã
ããããæçµçãªå¥åã®ã³ã³ããŒãã³ããã©ãããã¹ãããã©ã®ããã«ããŠç¥ãã®ã§ããããïŒ æ°ããé¢æ°ãŸãã¯ãªããžã§ã¯ããäœæãããšããšåãã¡ãœããã䜿çšããŠæ±ºå®ããŸãã ãããã®æ¹æ³ã®1ã€ã¯ãå¯äžã®è²¬ä»»ã®ååã§ã ãã€ãŸããã³ã³ããŒãã³ãã¯ãçæ³çã«ã¯ã1ã€ã®ãã®/ãšã³ãã£ãã£ã®ã¿ãäœæããå¿
èŠããããŸãã ã³ã³ããŒãã³ããä»ã®ã³ã³ããŒãã³ãã§ç¹°ãè¿ãããè€æ°ã®ãšã³ãã£ãã£ãäœæããå Žåã¯ãããå°ããªã³ã³ããŒãã³ãã«å解ããå¿
èŠããããŸãã
JSONããŒã¿ã¢ãã«ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãšããŠè¡šç€ºããé »åºŠãé«ãã»ã©ãããŒã¿ã¢ãã«ãæ£ããæ§ç¯ãããŠããã°ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ïŒãããã£ãŠã³ã³ããŒãã³ãã®æ§é ïŒãçŸããèŠãããšããçµè«ã«ãã°ããéããŸãã ãã®çç±ã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãšããŒã¿ã¢ãã«ãååãšããŠåãæ
å ±ã¢ãŒããã¯ãã£ã«æºæ ããŠããããã§ããã€ãŸãããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãã³ã³ããŒãã³ãã«åå²ããã®ã¯ç°¡åãªäœæ¥ã§ããããšãå€ããšããããšã§ããããŒã¿ã¢ãã«ãã

ã¬ã€ã¢ãŠããããããããã«ãåçŽãªã¢ããªã±ãŒã·ã§ã³ã«ã¯5ã€ã®ã³ã³ããŒãã³ãããããŸãã åã³ã³ããŒãã³ãããã«ãã«ã©ãŒã®ããã¯ã¹ã§åŒ·èª¿è¡šç€ºããŸããã
FilterableProductTable
ïŒãªã¬ã³ãžïŒïŒããŒãã«å
šäœãå«ãŸããŠããŸãSearchBar
ïŒéïŒïŒãã¹ãŠã®ãŠãŒã¶ãŒå
¥åãåãå
¥ããŸãProductTable
ïŒç·è²ïŒïŒ ãŠãŒã¶ãŒå
¥åã«åºã¥ããŠããŒã¿ã»ããã衚瀺ããã³ãã£ã«ã¿ãŒã ãŸããProductCategoryRow
ïŒã¿ãŒã³ã€ãºïŒïŒåã«ããŽãªãŒã®ã¿ã€ãã«ã衚瀺ããŸãProductRow
ïŒèµ€ïŒïŒåã¢ã€ãã ã®è¡ã衚瀺ããŸã
ProductTable
ãèŠããšãããŒãã«ã¿ã€ãã«ïŒã©ãã«ãNameããšãPriceããå«ãïŒãå¥ã®ã³ã³ããŒãã³ãã§éžæãããŠããªãããšãããããŸãã ããã¯å¥œã¿ã®åé¡ã§ããããã®ãªãã·ã§ã³ãŸãã¯ãã®ãªãã·ã§ã³ã«ã¯åŒæ°ããããŸãã ãã®äŸã§ã¯ã ProductTable
ã®è²¬ä»»ã§ããããŒã¿ã»ããã®èŠèŠåã®äžéšã§ããããã ProductTable
äžéšãšããŠèŠåºããæ®ããŸããã ãã ããã¿ã€ãã«ãããè€éãªå ŽåïŒããšãã°ãåã§äžŠã¹æ¿ããæ©èœãè¿œå ããå¿
èŠãããå ŽåïŒããã¡ãããå¥ã®ProductTableHeader
ã³ã³ããŒãã³ãã«åé¢ããŸãã
ã¬ã€ã¢ãŠãã§ã³ã³ããŒãã³ããå®çŸ©ããã®ã§ãã³ã³ããŒãã³ããéå±€ã§ãã©ãŒãããããŸãããã ç°¡åã§ãã ã¬ã€ã¢ãŠãå
ã®å¥ã®ã³ã³ããŒãã³ãã®äžéšã§ããã³ã³ããŒãã³ãã¯ãéå±€å
ã®åå«ã®ããã«èŠããå¿
èŠããããŸãã
FilterableProductTable
SearchBar
ProductTable
ProductCategoryRow
ProductRow
ã¹ããã2ïŒReactã§éçããŒãžã§ã³ãäœæãã
HTML <div id="container"> </div>
Javascript class ProductCategoryRow extends React.Component { render() { return <tr><th colSpan="2">{this.props.category}</th></tr>; } } class ProductRow extends React.Component { render() { var name = this.props.product.stocked ? this.props.product.name : <span style={{color: 'red'}}> {this.props.product.name} </span>; return ( <tr> <td>{name}</td> <td>{this.props.product.price}</td> </tr> ); } } class ProductTable extends React.Component { render() { var rows = []; var lastCategory = null; this.props.products.forEach(function(product) { if (product.category !== lastCategory) { rows.push(<ProductCategoryRow category={product.category} key={product.category} />); } rows.push(<ProductRow product={product} key={product.name} />); lastCategory = product.category; }); return ( <table> <thead> <tr> <th>Name</th> <th>Price</th> </tr> </thead> <tbody>{rows}</tbody> </table> ); } } class SearchBar extends React.Component { render() { return ( <form> <input type="text" placeholder="Search..." /> <p> <input type="checkbox" /> {' '} Only show products in stock </p> </form> ); } } class FilterableProductTable extends React.Component { render() { return ( <div> <SearchBar /> <ProductTable products={this.props.products} /> </div> ); } } var PRODUCTS = [ {category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'}, {category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'}, {category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'}, {category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'}, {category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'}, {category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'} ]; ReactDOM.render( <FilterableProductTable products={PRODUCTS} />, document.getElementById('container') );
ã³ã³ããŒãã³ãéå±€ãã§ããã®ã§ãä»åºŠã¯ã¢ããªã±ãŒã·ã§ã³ãå®è£
ããŸãã æãç°¡åãªæ¹æ³ã¯ãããŒã¿ã¢ãã«ãšãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã衚瀺ããããã€ã³ã¿ã©ã¯ãã£ãæ©èœããªãéçããŒãžã§ã³ããå§ããããšã§ãã éçéšåãšå¯Ÿè©±åéšåã®åé¢ã¯ã次ã®ãããªåªãããœãªã¥ãŒã·ã§ã³ã§ãã éçããŒãžã§ã³ãå®è£
ããã¿ã¹ã¯ã¯ãæèããã»ã¹ãæå°éã«æããŠããŒããŒããã倧éã®ããã¹ããå
¥åããããšã§ããäžæ¹ãã€ã³ã¿ã©ã¯ãã£ãæ©èœãå®è£
ããã«ã¯ãæèããã»ã¹ãšããŒããŒãããã®å°ããªå
¥åãå¿
èŠã§ãã 次ã«ããªããããªã®ããèŠãŠãããŸãã
éçããŒãžã§ã³ã®å®è£
ã¯ãããŒã¿ã¢ãã«ã®è¡šç€ºïŒã¬ã³ããªã³ã°ïŒã§ãããã®éãä»ã®ã³ã³ããŒãã³ãã䜿çšããã³ã³ããŒãã³ããäœæãã propsïŒããããã£ïŒãä»ããŠããŒã¿ãéä¿¡ããŸã ã å°éå
·ã¯ãReactã³ã³ããŒãã³ãéå±€ã®èŠªããåã«ããŒã¿ã転éããããã®ããŒã«ã§ãã Reactã«ã¯ç¶æ
ã®ãããªæŠå¿µããããŸã -éçããŒãžã§ã³ãäœæãããšãã«ç¶æ
ã 䜿çšããªãã§ãã ããã å·ã®äž»ãªç®çã¯å¯Ÿè©±æ§ã§ãããæéãšãšãã«å€åããããŒã¿ã®éä¿¡ãšèšé²ã«å¿
èŠã§ãã çŸæç¹ã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã®éçããŒãžã§ã³ãäœæããŠãããããStateã䜿çšããå¿
èŠã¯ãããŸããã
ã¢ããªã±ãŒã·ã§ã³ããããããŠã³ãŸãã¯ããã ã¢ããã§å®è£
ã§ããŸãã ã€ãŸããäžäœã®éå±€ã¬ãã«ã®ã³ã³ããŒãã³ãïŒ FilterableProductTable
å§ãŸãïŒãæ§ç¯ããããšããéå§ãããããã®éã«äžäœã¬ãã«ïŒ ProductRow
ïŒããæ§ç¯ããããšãã§ããŸãã åçŽãªã¢ããªã±ãŒã·ã§ã³ã§ã¯ãéåžžãäžããäžãžããããŠãã倧ããªã¢ããªã±ãŒã·ã§ã³ã§ã¯äžããäžãžãšç§»åããã³ã³ããŒãã³ãã®å®è£
æã«äžŠè¡ããŠãã¹ããäœæããæ¹ãç°¡åã§ãã
ãã®æé ã®æåŸã«ãããŒã¿ã¢ãã«ã衚瀺ããåå©çšå¯èœãªã³ã³ããŒãã³ãã®ã©ã€ãã©ãªãäœæãããŸãã ããã¯éçããŒãžã§ã³ã§ããrender()
ãã³ã³ããŒãã³ãã«ã¯render()
ã¡ãœããã®ã¿ãããrender()
ã éå±€ã®æäžäœã«ããã³ã³ããŒãã³ãïŒ FilterableProductTable
ïŒã¯ã propsãä»ããŠããŒã¿ã¢ãã«ãåãåããŸãã åºã«ãªãããŒã¿ã¢ãã«ã«å€æŽãå ãã ReactDOM.render()
å床åŒã³åºããšããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãæŽæ°ãããŸãã ããã¯æ£ãããããŸãã-ããã¯æ¬åœã«éåžžã«åçŽãªã®ã§ãè€éãªãã®ã¯äœããããŸãããïŒ React one - way ããŒã¿ãããŒ ïŒ one - wayãã€ã³ãã£ã³ã°ãšãåŒã°ããŸãïŒã¯ãã¢ãžã¥ãŒã«æ§ãšé床ãæäŸããŸãã
å°ããªäœè«ïŒããããã£ïŒpropsïŒãšç¶æ
ïŒstateïŒ
Reactã«ã¯ãããŒã¿ã®2ã€ã®ãã¢ãã«ããå°éå
·ãšç¶æ
ããããŸãã 2ã€ã®éããç解ããããšãéèŠã§ãã éããããããªãå Žåã¯ãå
¬åŒããã¥ã¡ã³ãã®å¯Ÿå¿ããã»ã¯ã·ã§ã³ãå床ãèªã¿ãã ããã
æé 3ïŒãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®ç¶æ
ã®æå°ïŒãã ãååãªïŒè¡šçŸã決å®ãã
ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãã€ã³ã¿ã©ã¯ãã£ãã«ããã«ã¯ãåºã«ãªãããŒã¿ã¢ãã«ã®å€æŽãç»é²ã§ããå¿
èŠããããŸãã Reactã§ã¯ãããã¯åã«stateã§è¡ãããŸãã
æ£ããã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããã«ã¯ããŸããã¢ããªã±ãŒã·ã§ã³ã«å¿
èŠãªå¯å€ç¶æ
ã®æå°ã»ãããèæ
®ããå¿
èŠããããŸãã DRYã®ååã«åŸãïŒ èªåèªèº«ãç¹°ãè¿ããªãã§ãã ãã ã çæ³çã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ç¶æ
ã®æå°è¡šçŸã«ã¯ãå¿
èŠãªãšãã«å©çšå¯èœãªããŒã¿ïŒå°éå
·ãšç¶æ
ïŒã«åºã¥ããŠèšç®ã§ãããã®ãå«ããªãã§ãã ããã äŸïŒTo Doãªã¹ãã衚瀺ããã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããå ŽåãTo Doã¬ã³ãŒããå«ãé
åå
ã«ãšã©ãŸããŸã-To Doã¢ã€ãã ã®æ°ã衚瀺ããå¥ã®Statuså€æ°ãäœæããªãã§ãã ããã 代ããã«ãã±ãŒã¹ã®æ°ã衚瀺ããå¿
èŠããããã®ç¬éã«ãæ¢åã®é
åã®é·ããååŸããŠãã ããã
ã¢ããªã±ãŒã·ã§ã³ã®ãã¹ãŠã®ããŒã¿ãŠãããã«ã€ããŠèããŸãã ãããŸã
- ãªãªãžãã«è£œåãªã¹ã
- ãŠãŒã¶ãŒãå
¥åããæ€çŽ¢ããã¹ã
- ãã§ãã¯ããã¯ã¹å€
- ãã£ã«ã¿ãŒããã補åãªã¹ã
åé
ç®ã調ã¹ãŠããããç¶æ
ãã©ãããå€æããŸãããã åããŒã¿ãŠãããã«ã€ããŠã3ã€ã®è³ªåãããå¿
èŠããããŸãã
- ãã®ããŒã¿ã¯ç¥å
ããå°éå
·ãä»ããŠéä¿¡ãããŸããïŒ ãããããªããããã¯ããããåœå®¶ã§ã¯ãããŸããã
- ãã®ããŒã¿ã¯æéãšãšãã«å€åããŸãããïŒ ãããããªããããã¯ããããåœå®¶ã§ã¯ãããŸããã
- ã³ã³ããŒãã³ãã§å©çšå¯èœãªïŒå°éå
·ãšç¶æ
ã§ïŒã«åºã¥ããŠãã®ããŒã¿ãèšç®ã§ããŸããïŒ ãã®å Žåãããã¯å·ã§ã¯ãããŸããã
補åã®å
ã®ãªã¹ãã¯å°éå
·ãä»ããŠéä¿¡ããããããã¹ããŒã¿ã¹ã§ã¯ãããŸããã æ€çŽ¢ããã¹ããšãã§ãã¯ããã¯ã¹ã®å€ã¯æéãšãšãã«å€åããå¯èœæ§ããããå©çšå¯èœãªããŒã¿ããèšç®ããããšã¯ã§ããŸãã-ãããã¯ç¶æ
ã§ãã ãããŠæåŸïŒå
ã®è£œåãªã¹ããæ€çŽ¢ããã¹ãããã§ãã¯ããã¯ã¹ã®å€ãçµã¿åãããŠããã£ã«ã¿ãŒããã補åãªã¹ããèšç®ã§ããŸã-ããã¯å·ã§ã¯ãããŸããã
ãã®çµæãç§ãã¡ã®å·ã¯ïŒ
- ãŠãŒã¶ãŒãå
¥åããæ€çŽ¢ããã¹ã
- ãã§ãã¯ããã¯ã¹å€
ã¹ããã4ïŒã¹ããŒã¿ã¹ã®å Žæã決å®ãã
HTML <div id="container"> </div>
Javascript class ProductCategoryRow extends React.Component { render() { return (<tr><th colSpan="2">{this.props.category}</th></tr>); } } class ProductRow extends React.Component { render() { var name = this.props.product.stocked ? this.props.product.name : <span style={{color: 'red'}}> {this.props.product.name} </span>; return ( <tr> <td>{name}</td> <td>{this.props.product.price}</td> </tr> ); } } class ProductTable extends React.Component { render() { var rows = []; var lastCategory = null; this.props.products.forEach((product) => { if (product.name.indexOf(this.props.filterText) === -1 || (!product.stocked && this.props.inStockOnly)) { return; } if (product.category !== lastCategory) { rows.push(<ProductCategoryRow category={product.category} key={product.category} />); } rows.push(<ProductRow product={product} key={product.name} />); lastCategory = product.category; }); return ( <table> <thead> <tr> <th>Name</th> <th>Price</th> </tr> </thead> <tbody>{rows}</tbody> </table> ); } } class SearchBar extends React.Component { render() { return ( <form> <input type="text" placeholder="Search..." value={this.props.filterText} /> <p> <input type="checkbox" checked={this.props.inStockOnly} /> {' '} Only show products in stock </p> </form> ); } } class FilterableProductTable extends React.Component { constructor(props) { super(props); this.state = { filterText: '', inStockOnly: false }; } render() { return ( <div> <SearchBar filterText={this.state.filterText} inStockOnly={this.state.inStockOnly} /> <ProductTable products={this.props.products} filterText={this.state.filterText} inStockOnly={this.state.inStockOnly} /> </div> ); } } var PRODUCTS = [ {category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'}, {category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'}, {category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'}, {category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'}, {category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'}, {category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'} ]; ReactDOM.render( <FilterableProductTable products={PRODUCTS} />, document.getElementById('container') );
ãã®ãããã¢ããªã±ãŒã·ã§ã³ã¹ããŒã¿ã¹ã®æå°ã»ãããå®çŸ©ããŸããã 次ã®ã¹ãããã§ã¯ãã©ã®ã³ã³ããŒãã³ãããã®ç¶æ
ãå€æŽãŸãã¯ææãããã決å®ããŸãã
èŠç¢ºèªïŒReactã¯ãã³ã³ããŒãã³ãéå±€ã§äžæ¹åã®ããŒã¿è»¢éãè¡ããŸãã ãããããã©ã®ã³ã³ããŒãã³ããåœã®ææè
ã§ããå¿
èŠããããã¯ãããããããã«ã¯æããã§ã¯ãããŸããã ãã®éšåã¯åå¿è
ã«ãšã£ãŠã¯é£ããå Žåãå€ãã®ã§ã次ã®æé ã«åŸã£ãŠãã®è³ªåãèŠã€ããŠãã ããã
ã¢ããªã±ãŒã·ã§ã³ã®ã¹ããŒã¿ã¹ãŠãããããšã«ïŒ
- ãã®ç¶æ
ã«åºã¥ããŠäœãã衚瀺ïŒã¬ã³ããªã³ã°ïŒãããã¹ãŠã®ã³ã³ããŒãã³ããèå¥ããŸãã
- ãããã®ã³ã³ããŒãã³ãã®å
±éã®ç¥å
ïŒãã®ã¹ããŒã¿ã¹ãå¿
èŠãšãããã¹ãŠã®ã³ã³ããŒãã³ãã®äžã®éå±€å
ã®åäžã®ã³ã³ããŒãã³ãïŒãèŠã€ããŸãã
- èŠã€ãã£ãå
±éã®ç¥å
ãŸãã¯äžäœã®éå±€ã®ã³ã³ããŒãã³ãã¯ãåœå®¶ã®ææè
ã«ä»»åœã§ããŸãã
- å
±éã®ç¥å
ãã³ã³ããŒãã³ãéå±€ã«ãªãå Žåã¯ããããåœå®¶ã®ææè
ã«ããããã ãã«ãããé«ãã¬ãã«ã®ã³ã³ããŒãã³ããäœæããå¿
èŠããããŸãã
ããã§ã¯ããã®æŠç¥ãã¢ããªã±ãŒã·ã§ã³ã«é©çšããŸãããã
ProductTable
ã³ã³ããŒãã³ãã«ã¯ã補åã®ãªã¹ãããã£ã«ã¿ãŒåŠçããããã®Stateãå¿
èŠã§ããã SearchBar
ã³ã³ããŒãã³ãã«ã¯ãæ€çŽ¢ã¯ãšãªãšãã§ãã¯ããã¯ã¹ã®ã¹ããŒã¿ã¹ã衚瀺ããããã®Stateãå¿
èŠã§ãã- ãããã®å
±éã®ç¥å
ã¯
FilterableProductTable
ã³ã³ããŒãã³ãã§ãã - ãããã£ãŠãæŠå¿µçã«ã¯ããªã¹ããšéžæãããå€ã®ãã£ã«ã¿ãªã³ã°ã®å
±éç¹ã¯
FilterableProductTable
ã³ã³ããŒãã³ãã«ãããŸã
ããŠãStateãFilterableProductTable
ã³ã³ããŒãã³ãã«é
眮ããå¿
èŠããããšå€æããŸããã æåã«ãã€ã³ã¹ã¿ã³ã¹ããããã£this.state = {filterText: '', inStockOnly: false}
ãFilterableProductTable
ã³ã³ããŒãã³ãã®constructor
FilterableProductTable
ãã¢ããªã±ãŒã·ã§ã³ã®åæç¶æ
ã決å®ããŸãã 次ã«ã inStockOnly
ã䜿çšããŠfilterText
ããã³inStockOnly
ãProductTable
ããã³SearchBar
ã³ã³ããŒãã³ãã«SearchBar
ãŸãã æåŸã®ã¹ãããã¯ã å°éå
·ã䜿çšããŠProductTable
æååããã£ã«ã¿ãŒåŠçãã SearchBar
ãã©ãŒã ãã£ãŒã«ãå€ãèšå®ããããšSearchBar
ã
ã¢ããªã±ãŒã·ã§ã³ãèµ·åããŠããã®åäœã確èªã§ããŸãfilterText
ã³ã³ããŒãã³ãFilterableProductTable
ã§filterText
å€ã'ball'
ããã¢ããªã±ãŒã·ã§ã³ããªããŒãããŸãã ããŒã¿ããŒãã«ãæ£ããæŽæ°ãããŠããããšãããããŸãã
ã¹ããã5ïŒããŒã¿ãããŒãè¿œå ãã
HTML <div id="container"> </div>
Javascript class ProductCategoryRow extends React.Component { render() { return (<tr><th colSpan="2">{this.props.category}</th></tr>); } } class ProductRow extends React.Component { render() { var name = this.props.product.stocked ? this.props.product.name : <span style={{color: 'red'}}> {this.props.product.name} </span>; return ( <tr> <td>{name}</td> <td>{this.props.product.price}</td> </tr> ); } } class ProductTable extends React.Component { render() { var rows = []; var lastCategory = null; this.props.products.forEach((product) => { if (product.name.indexOf(this.props.filterText) === -1 || (!product.stocked && this.props.inStockOnly)) { return; } if (product.category !== lastCategory) { rows.push(<ProductCategoryRow category={product.category} key={product.category} />); } rows.push(<ProductRow product={product} key={product.name} />); lastCategory = product.category; }); return ( <table> <thead> <tr> <th>Name</th> <th>Price</th> </tr> </thead> <tbody>{rows}</tbody> </table> ); } } class SearchBar extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange() { this.props.onUserInput( this.filterTextInput.value, this.inStockOnlyInput.checked ); } render() { return ( <form> <input type="text" placeholder="Search..." value={this.props.filterText} ref={(input) => this.filterTextInput = input} onChange={this.handleChange} /> <p> <input type="checkbox" checked={this.props.inStockOnly} ref={(input) => this.inStockOnlyInput = input} onChange={this.handleChange} /> {' '} Only show products in stock </p> </form> ); } } class FilterableProductTable extends React.Component { constructor(props) { super(props); this.state = { filterText: '', inStockOnly: false }; this.handleUserInput = this.handleUserInput.bind(this); } handleUserInput(filterText, inStockOnly) { this.setState({ filterText: filterText, inStockOnly: inStockOnly }); } render() { return ( <div> <SearchBar filterText={this.state.filterText} inStockOnly={this.state.inStockOnly} onUserInput={this.handleUserInput} /> <ProductTable products={this.props.products} filterText={this.state.filterText} inStockOnly={this.state.inStockOnly} /> </div> ); } } var PRODUCTS = [ {category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'}, {category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'}, {category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'}, {category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'}, {category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'}, {category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'} ]; ReactDOM.render( <FilterableProductTable products={PRODUCTS} />, document.getElementById('container') );
çŸåšã®æé ã§ã¯ãã³ã³ããŒãã³ãã®éå±€ãäžã«ç§»åããå°éå
·ãšç¶æ
ãæ£ãã転éããã³äœ¿çšããã¢ããªã±ãŒã·ã§ã³ãäœæããŸããã å察æ¹åã®ããŒã¿è»¢éã®ãµããŒããè¿œå ãããšããæ¥ãŸãããéå±€ã®äžäœã«ãããã©ãŒã ã®ã³ã³ããŒãã³ãã¯ãäœããã®FilterableProductTable
ã³ã³ããŒãã³ãã®ã¹ããŒã¿ã¹ãæŽæ°ããå¿
èŠããããŸãã
ãã®ããŒã¿ã¹ããªãŒã ãäœæããããã®Reactã¡ã«ããºã ã¯ãããã°ã©ã ã®åäœãç°¡åã«ç解ã§ããããã«èšèšãããŠããŸãããåŸæ¥ã®åæ¹åããŒã¿ãã€ã³ãã£ã³ã°ãããå°ãå€ãã®ããŒããŒãå
¥åãå¿
èŠã§ãã
ãµã³ãã«ã®çŸåšã®ããŒãžã§ã³ã§ããã¹ããå
¥åããããããã¯ã¹ããã§ãã¯ããããšãããšãReactã¯å
¥åãç¡èŠããããšãããããŸãã ããã¯ãç§ãã¡ãæå³çã«ç¢ºç«ãããã®ã§ãã å€ããããã£ã®å€ãã FilterableProductTable
ã³ã³ããŒãã³ãããæž¡ãããstate
åžžã«çããinput
ã«èšå®ããŸãã
ç§ãã¡ãäœããããã®ãèããŠã¿ãŸãããã ãŠãŒã¶ãŒããã©ãŒã ãå€æŽãããã³ã«ãã¹ããŒã¿ã¹ãæŽæ°ãããŠãŠãŒã¶ãŒå
¥åã衚瀺ãããŸãã ã³ã³ããŒãã³ãã¯ç¬èªã®ç¶æ
ã®ã¿ãæŽæ°ããFilterableProductTable
ããã FilterableProductTable
ã³ã³ããŒãã³ãFilterableProductTable
ã³ãŒã«ããã¯ã¡ã«ããºã ãSearchBar
ã³ã³ããŒãã³ãã«æž¡ãFilterableProductTable
ããããŸããããã¯ãç¶æ
ãæŽæ°ããå¿
èŠããããã³ã«éç¥ããŸãã ãããå ±åããã«ã¯ããã©ãŒã ã®ã³ã³ããŒãã³ãã§onChange
ã€ãã³ãã䜿çšããŸãã 次ã«ã FilterableProductTable
ã³ã³ããŒãã³ãã«ãã£ãŠæž¡ãããã³ãŒã«ããã¯ãsetState()
ãåŒã³åºããã¢ããªã±ãŒã·ã§ã³ãæŽæ°ãããŸãã
è€éã«èŠããŸãããå®éã«ã¯ã»ãã®æ°è¡ã®ã³ãŒãã§ãã ãããŠãã¢ããªã±ãŒã·ã§ã³å
šäœã§ããŒã¿ãã©ã®ããã«éä¿¡ããããã¯æ¬åœã«ééçã«èŠããŸãã
ããã ãã§ã
ãã®ãã¥ãŒããªã¢ã«ã§ãReactã®ã³ã³ããŒãã³ããšã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããéã®èãæ¹ãç解ããŠããã ããã°å¹žãã§ãã 以åãããå°ãå€ãã³ãŒããå
¥åããå¿
èŠããããŸããããã³ãŒãã¯æžãããŠãããããäœåãé »ç¹ã«èªã¿åãããéææ§ãšã¢ãžã¥ãŒã«æ§ã®ããã«ã³ãŒããèªã¿ãããããšãèŠããŠãããŠãã ããã 倧èŠæš¡ãªã©ã€ãã©ãªãŸãã¯ã¢ããªã±ãŒã·ã§ã³ã®äœæãéå§ãããšããã«ããã®éææ§ãšã¢ãžã¥ãŒã«æ§ãçã«è©äŸ¡ããŸããåå©çšã®å¯èœæ§ã«ãããã³ãŒãã®å
¥åãå°ãªããªããšããäºå®ãå¿
ãçããŸãã
åºå
žïŒ React-ã¯ã€ãã¯ã¹ã¿ãŒã-Reactã§èãã