1.分離組件
2.創建靜態版本
import React from 'react';
import ReactDOM from 'react-dom';
class SearchBar extends React.Component {
constructor(props) {
super(props);
}
render() {
return (<div>
<input placeholder = "Search..." /> < p > <input type="checkbox"/>
only show products in stock < /p></div>)
}
}
class ProductTable extends React.Component {
render() {
return (<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
<tr>
<th>Sporting Goods</th>
</tr>
<tr>
<td>Foodball</td>
<td>$49.99</td>
</tr>
</thead>
<tbody></tbody>
</table>)
}
}
const 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'
}];
class FilterableProductTable extends React.Component {
render() {
return (<div>
<SearchBar/>
<ProductTable products={this.props.products}/>
</div>)
}
}
ReactDOM.render(<FilterableProductTable products={PRODUCTS}/>, document.getElementById('root'));
效果如下:
現在將數據用props引入
import React from 'react';
import ReactDOM from 'react-dom';
class SearchBar extends React.Component {
constructor(props) {
super(props);
}
render() {
return (<div>
<input placeholder = "Search..." /> < p > <input type="checkbox"/>
only show products in stock < /p></div>)
}
}
class ProductRow extends React.Component {
render() {
return (<tr>
<td>{this.props.product.stocked?this.props.product.name:<span style={{color: 'red'}} >{this.props.product.name}</span>}</td>
<td>{this.props.product.price}</td>
</tr>);
}
}
class ProductCategoryRow extends React.Component {
render() {
return (<tr>
<th>{this.props.title}</th>
</tr>);
}
}
class ProductTable extends React.Component {
render() {
//rowProducts爲對象
// const products = this.props.products;
// let rowProducts = {};
// for (let i = 0; i < products.length; i++) {
// if (!rowProducts.hasOwnProperty(products[i].category)) {
// rowProducts[products[i].category] = new Array();
// } else {
// rowProducts[products[i].category].push(products[i]);
// }
// }
//rowProducts爲Map
const products = this.props.products;
let rowProducts = new Map();
for (let i = 0; i < products.length; i++) {
if (!rowProducts.has(products[i].category)) {
rowProducts.set(products[i].category, new Array());
rowProducts.get(products[i].category).push(products[i]);
} else {
rowProducts.get(products[i].category).push(products[i]);
}
}
console.log(rowProducts)
let row = [];
for (let key of rowProducts.keys()) {
row.push(<ProductCategoryRow title = {key} key={key}/>);
for (let i = 0; i < rowProducts.get(key).length; i++) {
row.push(<ProductRow product={rowProducts.get(key)[i]} key={rowProducts.get(key)[i].name}/>);
}
}
return (<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody> {row}</tbody>
</table>)
}
}
const 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'
}];
class FilterableProductTable extends React.Component {
render() {
return (<div>
<SearchBar/>
<ProductTable products={this.props.products}/>
</div>)
}
}
ReactDOM.render(<FilterableProductTable products={PRODUCTS}/>, document.getElementById('root'));
效果如下:
3.將函數傳遞給子組件
import React from 'react';
import ReactDOM from 'react-dom';
class SearchBar extends React.Component {
constructor(props) {
super(props);
this.filterText = props.filterText;
this.changeProductInput = props.changeProductInput;
this.changeProductCheckBox = props.changeProductCheckBox;
this.changeFilterText = this.changeFilterText.bind(this);
this.changeCheckBox = this.changeCheckBox.bind(this);
}
changeFilterText(e) {
// console.log(e.target.value);
this.changeProductInput(e.target.value);
}
changeCheckBox(e) {
//console.log(e.target.checked);
this.changeProductCheckBox(e.target.checked);
}
render() {
return (<div>
<input placeholder = "Search..." onChange={this.changeFilterText} /> < p > <input type="checkbox"
onChange={this.changeCheckBox} />
only show products in stock < /p></div>)
}
}
class ProductRow extends React.Component {
render() {
return (<tr>
<td>{this.props.product.stocked?this.props.product.name:<span style={{color: 'red'}} >{this.props.product.name}</span>}</td>
<td>{this.props.product.price}</td>
</tr>);
}
}
class ProductCategoryRow extends React.Component {
render() {
return (<tr>
<th>{this.props.title}</th>
</tr>);
}
}
class ProductTable extends React.Component {
constructor(props) {
super(props);
// this.filterText = props.filterText;
}
render() {
//rowProducts爲對象
// const products = this.props.products;
// let rowProducts = {};
// for (let i = 0; i < products.length; i++) {
// if (!rowProducts.hasOwnProperty(products[i].category)) {
// rowProducts[products[i].category] = new Array();
// } else {
// rowProducts[products[i].category].push(products[i]);
// }
// }
//rowProducts爲Map
//console.log(this.props.filterText);
// console.log(this.props.inStockOnly;)
const inStockOnly = this.props.inStockOnly;
const products = this.props.products;
let rowProducts = new Map();
for (let i = 0; i < products.length; i++) {
if (!rowProducts.has(products[i].category)) {
rowProducts.set(products[i].category, new Array());
if (this.props.filterText === '') {
rowProducts.get(products[i].category).push(products[i]);
} else {
if (this.props.filterText === products[i].name.slice(0, this.props.filterText.length)) {
rowProducts.get(products[i].category).push(products[i]);
}
}
} else {
if (this.props.filterText === '') {
rowProducts.get(products[i].category).push(products[i]);
} else {
if (this.props.filterText === products[i].name.slice(0, this.props.filterText.length)) {
rowProducts.get(products[i].category).push(products[i]);
}
}
}
}
//處理數據
//根據條件刪除字典裏的數據,上一步的數據處理也可以放這裏來
for (let key of rowProducts.keys()) {
for (let i = 0; i < rowProducts.get(key).length; i++) {
if (inStockOnly) {
if (!rowProducts.get(key)[i].stocked) {
rowProducts.get(key).splice(i, 1);
}
}
}
}
let row = [];
for (let key of rowProducts.keys()) {
row.push(<ProductCategoryRow title = {key} key={key}/>);
for (let i = 0; i < rowProducts.get(key).length; i++) {
row.push(<ProductRow product={rowProducts.get(key)[i]} key={rowProducts.get(key)[i].name}/>);
}
}
return (<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody> {row}</tbody>
</table>)
}
}
const PRODUCTS = [{
category: 'Sporting Goods',
price: '$49.99',
stocked: true,
name: 'Football'
}, {
category: 'Sporting Goods',
price: '$49.99',
stocked: true,
name: 'Footbal'
}, {
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'
}];
class FilterableProductTable extends React.Component {
constructor(props) {
super(props);
this.state = {
filterText: '',
inStockOnly: false
};
this.changeProductInput = this.changeProductInput.bind(this);
this.changeProductCheckBox = this.changeProductCheckBox.bind(this);
}
changeProductInput(value) {
this.setState({
filterText: value
});
}
changeProductCheckBox(value) {
this.setState({
inStockOnly: value
});
}
render() {
// console.log(this.state.filterText)
return (<div>
<SearchBar filterText={this.state.filterText}
inStockOnly={this.state.inStockOnly}
changeProductInput={this.changeProductInput}
changeProductCheckBox={this.changeProductCheckBox}
/>
<ProductTable products={this.props.products}
filterText={this.state.filterText}
inStockOnly={this.state.inStockOnly}
/>
</div>)
}
}
ReactDOM.render(<FilterableProductTable products={PRODUCTS}/>, document.getElementById('root'));