ReactDOM:
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'}
];
ReactDOM.render(
//將數據庫藉由props傳入最高層級Component
<FilterableProductTable products={PRODUCTS} />,
document.getElementById('root') //將結果渲染到HTML中
);
FilterableProductTable:
作為最高層級的Component,接收數據庫數據並將他利用props分給Sub Components
class FilterableProductTable extends React.Component {
render() {
return (
<div>
<SearchBar />
{/* 將從父層傳遞的數據庫傳遞給子層(ProductTable) */}
<ProductTable products={this.props.products} />
</div>
);
}
}
SearchBar :
class SearchBar extends React.Component {
render() {
return (
<form>
<input type="text" placeholder="Search..." />
<p>
<input type="checkbox" />
{' '}
Only show products in stock
</p>
</form>
);
}
}
ProductTable :
第二層Component,接收最高層級Component FilterableProductTable的數據庫資料(props)
class ProductTable extends React.Component {
render() {
const rows = [];
let lastCategory = null;
/*
將數據庫陣列內每個元素傳入function,function會先判斷category是否與前一個一樣,若不是的便會將"ProductCategoryRow"加入到row陣列中並把"category" 與 "key"利用props傳給子層;
若一樣便會把"ProductRow"加入到row陣列並將"product" 與 "key"利用props傳給子層
*/
//forEach : 將陣列內的每個元素,皆傳入並執行給定的函式一次。
this.props.products.forEach((product) => {
if (product.category !== lastCategory)
{
//push : 加一個或多個元素至陣列的末端
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>
);
}
}
可以藉由console.log觀看到row中的數據,將類別與商品名稱分類
//---------------------------------- 類別 ------------------------------------------//
0: {$$typeof: Symbol(react.element), key: "Sporting Goods", ref: null, props: {…}, type: ƒ, …}
//---------------------------------- 商品 ------------------------------------------//
1: {$$typeof: Symbol(react.element), key: "Football", ref: null, props: {…}, type: ƒ, …}
2: {$$typeof: Symbol(react.element), key: "Baseball", ref: null, props: {…}, type: ƒ, …}
3: {$$typeof: Symbol(react.element), key: "Basketball", ref: null, props: {…}, type: ƒ, …}
//---------------------------------- 類別 ------------------------------------------//
4: {$$typeof: Symbol(react.element), key: "Electronics", ref: null, props: {…}, type: ƒ, …}
//---------------------------------- 商品 ------------------------------------------//
5: {$$typeof: Symbol(react.element), key: "iPod Touch", ref: null, props: {…}, type: ƒ, …}
6: {$$typeof: Symbol(react.element), key: "iPhone 5", ref: null, props: {…}, type: ƒ, …}
7: {$$typeof: Symbol(react.element), key: "Nexus 7", ref: null, props: {…}, type: ƒ, …}
ProductCategoryRow :
第三層Component,接收父層(第二層Component ProductTable)所傳遞的數據庫(props)
class ProductRow extends React.Component {
render() {
const product = this.props.product;
//判斷數據庫中的stocked是否為true,若是則直接輸出商品名稱,若為否則將商品名稱改為紅色
const name = product.stocked ?
product.name :
<span style={{color: 'red'}}>
{product.name}
</span>;
return (
<tr>
<td>{name}</td>
<td>{product.price}</td>
</tr>
);
}
}
ProductRow :
第三層Component,接收父層(第二層Component ProductTable)所傳遞的數據庫(props)
class ProductCategoryRow extends React.Component {
render() {
const category = this.props.category;
return (
<tr>
{/* colSpan = "2"將<th>屬性輸出的元件跨兩格 */}
<th colSpan="2">
{category}
</th>
</tr>
);
}
}