流程圖 :
FilterableProductTable:
放置State的初始化,並將state透過props傳遞給子層(SearchBar / ProductTable)
class FilterableProductTable extends React.Component
{
constructor(props)
{
super(props);
//state初始化
this.state = {
filterText: '',
inStockOnly: false
};
}
render()
{
return (
<div>
{/* 將初始化的state利用props傳遞給Sub Component */}
<SearchBar
filterText={this.state.filterText}
inStockOnly={this.state.inStockOnly}
/>
<ProductTable
products={this.props.products}
filterText={this.state.filterText}
inStockOnly={this.state.inStockOnly}
/>
</div>
);
}
}
SearchBar :
接收父層的數據庫資料與state,並將牠放入html中
class SearchBar extends React.Component
{
render()
{
const filterText = this.props.filterText;
const inStockOnly = this.props.inStockOnly;
return (
<form>
{/* 將父層傳遞的State放入HTML元件中,設定初始狀態 */}
<input
type="text"
placeholder="Search..."
value={filterText} />
<p>
<input
type="checkbox"
checked={inStockOnly} />
{' '}
Only show products in stock
</p>
</form>
);
}
}
ProductTable:
接收父層的數據庫資料與state,並加入與html之間互動的判斷(表單填入資料與數據庫比對、checkedBox和庫存狀態)
class ProductTable extends React.Component
{
render()
{
const filterText = this.props.filterText;
const inStockOnly = this.props.inStockOnly;
const rows = [];
let lastCategory = null;
/*
將數據庫陣列內每個元素傳入function
function判斷:
1.判斷輸入表單的name是否是數據庫中的name,若不是(-1)則跳出function
2.判斷checkbox是否有被勾選(true)與是否沒有庫存(!(stocked=true) = false)
3.判斷category是否與前一個一樣,若不是的便會將"ProductCategoryRow"加入到row陣列中並把"category" 與 "key"利用props傳給子層;若一樣便會把"ProductRow"加入到row陣列並將"product" 與 "key"利用props傳給子層
*/
this.props.products.forEach((product) => {
//indexOf() : 回傳給定元素於陣列中第一個被找到之索引,若不存在於陣列中則回傳-1
if (product.name.indexOf(filterText) === -1)
{
return;
}
else if (inStockOnly && !product.stocked)
{
return;
}
else 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>
);
}
}