前言
接上一篇文章的代码片段,今天为大家提供另一组件——购物车计数,因为当初写组件时没有想到会有多复杂,所以写到后面才发现整个组件存在大的问题,开篇就不提bug在哪里了,结尾告诉大家,不过有兴趣的小伙伴们可以重构整个组件,可以联系我,我们一起来讨论。
组件结构
/*
* ShopCarTable
* ProductTable
* ProductRow
* ProductCount
* ProductTotal
*/
代码片段
interface Product {
id: string,
name: string,
price: number
}
interface ProductCount {
pid: string,
count: number
}
// ProductCount
interface ProductCountProps {
onCount: (c: number) => any;
count: number;
}
interface ProductCountState {
}
class ProductCountEditor extends React.Component<ProductCountProps, ProductCountState>{
handleClickAdd = () => this.props.onCount(this.props.count + 1)
handleClickRed = () => this.props.count > 0 && this.props.onCount(this.props.count - 1)
public render() {
return (
<form>
<input type="button" value="-" onClick={this.handleClickRed} />
<input type="text" value={this.props.count + ''} readOnly />
<input type="button" value="+" onClick={this.handleClickAdd} />
</form>
);
}
}
// ProductRow
interface ProductRowProps {
product: Product
count: number
onCount: (c:number)=>void
}
class ProductRow extends React.Component<ProductRowProps, {}>{
constructor(props: any) {
super(props);
}
public render() {
const {id, name, price} = this.props.product
const count = this.props.count
return (
<tr>
<td>{id}</td>
<td>{name}</td>
<td>{price}¥</td>
<td><ProductCountEditor count={count} onCount={this.props.onCount} /></td>
<td>{price * count}¥</td>
</tr>
);
}
}
// ProductTotal
interface ProductTotalProps {
total: number
}
function ProductTotal(props: ProductTotalProps) {
return (
<tfoot>
<tr>
<td colSpan={5}>总价: {props.total}¥</td>
</tr>
</tfoot>
);
}
// ProductTable
interface ProductTableProps {
products: Product[]
}
interface ProductTableState {
counts: ProductCount[]
}
class ProductTable extends React.Component<ProductTableProps, ProductTableState>{
constructor(props: ProductTableProps) {
super(props);
let counts: ProductCount[] = props.products.map(p => ({pid: p.id, count: 0}));
this.state = { counts };
}
public render() {
const products = this.props.products;
const counts = this.state.counts;
let productNodes = products.map(p => {
let c = counts.filter(c => c.pid===p.id)[0];
return (
<ProductRow key={p.id} product={p} count={c.count} onCount={count => {
let countsSlice = counts.slice();
console.log(countsSlice);
countsSlice.splice(counts.indexOf(c), 1, {pid:c.pid, count});
this.setState({ counts: countsSlice });
}} />
);
});
return (
<table>
<thead>
<tr>
<th>产品id</th>
<th>产品名称</th>
<th>产品单价</th>
<th>产品数量</th>
<th>产品总计</th>
</tr>
</thead>
<tbody>
{productNodes}
</tbody>
<ProductTotal total={this.state.counts.map(pc => {
return this.props.products.filter(p => p.id === pc.pid)[0].price * pc.count
}).reduce((sum,c)=>sum+c, 0)} />
</table>
);
}
}
let PRODUCTS: Product[] = [
{ id: '1', name: '背包', price: 49.99 },
{ id: '2', name: '衣服', price: 34 }
];
ReactDOM.render(
<ProductTable products={PRODUCTS} />,
document.getElementById('example')
);
结尾
大家发现这个大问题是什么了吗?
是我的数据结构一开始就没有定义好,所以我的计数实现才那么复杂。以后数据最好改成适合自己应用的结构。。。就像这个组件中,products跟counts没有组合在一起就很不方便了。
下面是实现的效果:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。