這個簡單的demo,功能是這樣的:
最左側是列表,點選列表項可檢視詳情,中間是詳情,詳情中有按鈕,點選可加入購物車,最右側是購物車,購物車自動更新總數和總價.
使用create-react-app建立.
程式碼如下:
index.js:
import React from `react`;
import ReactDOM from `react-dom`;
import Books from `./Books`;
import `../node_modules/bootstrap/dist/css/bootstrap.min.css`;
import `./styles/index.css`;
ReactDOM.render(
<Books />,
document.getElementById(`root`)
);
Books.js:
import React, { Component } from `react`;
import BookList from `./BookList`;
import BookDetail from `./BookDetail`;
import Car from `./Car`;
class Books extends Component {
constructor() {
super()
this.handleListClick = this.handleListClick.bind(this);
this.handleAddToCar = this.handleAddToCar.bind(this);
this.state = {
currentBook: null,
car: [],
totalNum: 0,
total: 0
};
}
handleListClick(book) {
this.setState({
currentBook: book
});
}
handleAddToCar(currentBook) {
let totalNum = this.state.totalNum;
let car = this.state.car;
let total = this.state.total;
let exist = false;
if (car.length) {
car.forEach(book => {
if (book.id === currentBook.id) {
book.number += 1;
totalNum += 1;
exist = true;
this.setState({
totalNum
});
}
});
}
if (!exist) {
car = car.concat(Object.assign({}, currentBook, {number:1}));
totalNum += 1;
this.setState({
car,
totalNum
});
}
total = car.map(book => (book.price * book.number)).reduce((prev, cur) => prev + cur);
this.setState({
total
});
}
render() {
return (
<div className=`row`>
<BookList books={this.props.books} listClick={this.handleListClick}/>
<BookDetail currentBook={this.state.currentBook} addToCar={this.handleAddToCar}/>
<Car {...this.state} />
</div>
);
}
}
Books.defaultProps = {
books: [
{
id: 1,
category: `CSS`,
title: `CSS權威指南`,
author: `Eric A. Meyer`,
price: 42
},
{
id: 2,
category: `JS`,
title: `JavaScript高階程式設計`,
author: `Nicholas C.Zakas`,
price: 69
},
{
id: 3,
category: `CSS`,
title: `精通CSS:高階Web標準解決方案`,
author: `巴德,科利森,莫爾`,
price: 25
}
]
};
export default Books;
BookList.js:
import React from `react`;
const BookList = ({books, listClick}) => {
return (
<div className=`col-md-2`>
<h2>圖書列表</h2>
<ul>
{books.map((book) => {
return (
<li key={book.id} onClick={() => listClick(book)}>
{book.title}
</li>
)
})}
</ul>
</div>
);
};
export default BookList;
BookDetail.js
import React from `react`;
const Bookdetail = ({currentBook, addToCar}) => {
if (!currentBook) return <div className=`col-md-4`><h2>選擇圖書</h2></div>
return (
<div className=`col-md-4`>
<h2>圖書詳情</h2>
<h3>{currentBook.title}</h3>
<p>作者:{currentBook.author}</p>
<p>價格:{currentBook.price}</p>
<p>編號:{currentBook.id}</p>
<button onClick={() => addToCar(currentBook)}>
放進購物車
</button>
</div>
);
};
export default Bookdetail;
Car.js:
import React from `react`;
const Car = ({car, totalNum, total}) => {
let result = car.length ? <p>共{totalNum}本 總價為{total}</p>: <p>購物車為空</p>;
return (
<div className=`col-md-6`>
<h2>購物車</h2>
<ul>
{
car.map((book, index) => {
return <li key={index}>
{book.title} 價格為: {book.price} 已選擇{book.number}本
</li>
})
}
</ul>
{result}
</div>
);
};
export default Car;