Skip to content

Instantly share code, notes, and snippets.

@arsan-irianto
Created February 11, 2019 16:07
Show Gist options
  • Save arsan-irianto/357fdc2b8cd2cbccdb2de73c54686c1e to your computer and use it in GitHub Desktop.
Save arsan-irianto/357fdc2b8cd2cbccdb2de73c54686c1e to your computer and use it in GitHub Desktop.
Refactor code from Thinking In React -> https://codepen.io/gaearon/pen/LzWZvb
import React, { useState } from 'react';
const ProductCategoryRow = (props) => {
const category = props.category;
return (
<tr>
<th colSpan="2">
{category}
</th>
</tr>
);
}
const ProductRow = (props) => {
const product = props.product;
const name = product.stocked ?
product.name :
<span style={{color: 'red'}}>
{product.name}
</span>;
return (
<tr>
<td>{name}</td>
<td>{product.price}</td>
</tr>
);
}
const ProductTable = (props) => {
const filterText = props.filterText;
const inStockOnly = props.inStockOnly;
const rows = [];
let lastCategory = null;
props.products.forEach((product) => {
if (product.name.indexOf(filterText) === -1) {
return;
}
if (inStockOnly && !product.stocked) {
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>
);
}
const SearchBar = (props) => {
const handleFilterTextChange = (e) => {
props.onFilterTextChange(e.target.value);
}
const handleInStockChange = (e) => {
props.onInStockChange(e.target.checked);
}
return (
<form>
<input
type="text"
placeholder="Search..."
value={props.filterText}
onChange={handleFilterTextChange}
/>
<p>
<input
type="checkbox"
checked={props.inStockOnly}
onChange={handleInStockChange}
/>
{' '}
Only show products in stock
</p>
</form>
);
}
const FilterableProductTable = (props) => {
const [filterText, setFilterText] = useState('')
const [inStockOnly, setInStockOnly] = useState(false)
const handleFilterTextChange = (filterText) => {
setFilterText(filterText)
}
const handleInStockChange = (inStockOnly) => {
setInStockOnly(inStockOnly)
}
return (
<div>
<SearchBar
filterText={filterText}
inStockOnly={inStockOnly}
onFilterTextChange={handleFilterTextChange}
onInStockChange={handleInStockChange}
/>
<ProductTable
products={props.products}
filterText={filterText}
inStockOnly={inStockOnly}
/>
</div>
);
}
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'}
];
const App = () => {
return (
<div className="App">
<FilterableProductTable products={PRODUCTS} />
</div>
);
}
export default App;
@r17x
Copy link

r17x commented Feb 11, 2019

Awesome @arsan-irianto 💯 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment