Skip to content

Instantly share code, notes, and snippets.

@akoskm
Last active September 12, 2019 14:04
Show Gist options
  • Save akoskm/69a69d6668246db3464ab01c0361d689 to your computer and use it in GitHub Desktop.
Save akoskm/69a69d6668246db3464ab01c0361d689 to your computer and use it in GitHub Desktop.
Use TypeScript to DRY up your components
onClick: (event: any) => void
interface TableRowProps extends ProductChangeListener {
product: Product;
selected: boolean;
}
export interface ProductChangeListener {
onProductChange: (event: MouseEvent) => void;
}
export interface ProductChangeListener {
onProductChange: (event: Product) => void;
}
const Sidebar = () => (
<div className="sidebar">
<DetailsPanel />
<DimensionsPanel />
</div>
);
type TableProps = {
selectedProduct: Product;
products: Array<Product>;
onProductChange: (event: any) => void;
};
import React from "react";
import { Product } from "./types";
type TableRowProps = {
product: Product;
onProductChange: (event: any) => void;
selected: boolean;
};
const TableRow = ({ product, onProductChange, selected }: TableRowProps) => {
return (
<tr
className={selected ? "selected" : undefined}
key={product.id}
onClick={() => {
onProductChange(product);
}}
>
<td>{product.id}</td>
<td>{product.name}</td>
<td>{product.sku}</td>
</tr>
);
};
export default TableRow;
import React from "react";
import PropTypes from "prop-types";
import TableRow from "./table-row";
const isSelected = (currProduct, selectedProduct) =>
selectedProduct && selectedProduct.id === currProduct.id;
const Table = ({ selectedProduct, products, onProductChange }) => (
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>SKU</th>
</tr>
</thead>
<tbody>
{products.map(currProduct => (
<TableRow
selected={isSelected(currProduct, selectedProduct)}
key={currProduct.id}
product={currProduct}
onProductChange={onProductChange}
/>
))}
</tbody>
</table>
);
Table.propTypes = {
selectedProduct: PropTypes.shape({
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
sku: PropTypes.string.isRequired,
dimensions: PropTypes.shape({
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
z: PropTypes.number.isRequired
})
}),
products: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
sku: PropTypes.string.isRequired,
dimensions: PropTypes.shape({
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
z: PropTypes.number.isRequired
}).isRequired
}).isRequired
),
onProductChange: PropTypes.func.isRequired
};
export default Table;
import React from "react";
import TableRow from "./table-row";
import { Product } from "./types";
type TableProps = {
selectedProduct: Product;
products: Array<Product>;
onProductChange: (event: any) => void;
};
const isSelected = (currProduct: Product, selectedProduct: Product) =>
selectedProduct && selectedProduct.id === currProduct.id;
const Table = ({ selectedProduct, products, onProductChange }: TableProps) => (
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>SKU</th>
</tr>
</thead>
<tbody>
{products.map((currProduct: Product) => (
<TableRow
selected={isSelected(currProduct, selectedProduct)}
key={currProduct.id}
product={currProduct}
onProductChange={onProductChange}
/>
))}
</tbody>
</table>
);
export default Table;
type TableRowProps = ProductChangeListener & {
product: Product;
selected: boolean;
};
export type Product = {
id: number;
name: string;
sku: string;
dimensions: {
x: number;
y: number;
z: number;
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment