Reactの流儀の実装例を書きました。
内容としては拙いものがありますが、記録として残しておきます。
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
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"}
];
function SearchBar(props){
return (
<div>
<input type='text' placeholder='Search...' onChange={props.handleInputSearchText} value={props.searchText}/>
<br />
<input type='checkbox' checked={props.onlyStocked} onChange={props.handleOnlyStocked} />Only show products in stock
</div>
);
}
function ProductTable(props){
const categories = [];
products.forEach(product => {
if(!categories.includes(product.category)){
categories.push(product.category);
}
});
const reactDom = [];
categories.forEach(category => {
reactDom.push(<ProductCategoryRow category={category} />);
products.forEach(product => {
if(category === product.category){
if(props.searchText === '' || product.name.includes(props.searchText)){
if(props.onlyStocked === true){
if(product.stocked === true){
reactDom.push(<ProductRow name={product.name} price={product.price} stocked={product.stocked}/>);
}
}else{
reactDom.push(<ProductRow name={product.name} price={product.price} stocked={product.stocked}/>);
}
}
}
});
});
return (
<table>
<thead>
<tr>
<th style={{textAlign: 'left'}}>Name</th>
<th style={{textAlign: 'left'}}>Price</th>
</tr>
</thead>
<tbody>
{reactDom}
</tbody>
</table>
);
}
function ProductCategoryRow(props){
return (
<tr>
<td><b>{props.category}</b></td>
</tr>
);
}
function ProductRow(props){
if(props.stocked){
return (
<tr>
<td>{props.name}</td>
<td> {props.price}</td>
</tr>
);
}else{
return (
<tr>
<td style={{color: 'red'}}>{props.name}</td>
<td> {props.price}</td>
</tr>
);
}
}
class FilterableProductTable extends React.Component {
constructor(props){
super(props);
this.state = {
onlyStocked: false,
searchText: ''
}
this.handleOnlyStocked = this.handleOnlyStocked.bind(this);
this.handleInputSearchText = this.handleInputSearchText.bind(this);
}
handleOnlyStocked(){
this.setState({onlyStocked: !this.state.onlyStocked});
}
handleInputSearchText(event){
this.setState({searchText: event.target.value});
}
render() {
return (
<div>
<SearchBar
onlyStocked={this.state.onlyStocked}
handleOnlyStocked={this.handleOnlyStocked}
handleInputSearchText={this.handleInputSearchText}
searchText={this.state.searchText}
/>
<ProductTable
onlyStocked={this.state.onlyStocked}
searchText={this.state.searchText}
/>
</div>
);
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<FilterableProductTable />)