React實現購物車功能

這個簡單的demo,功能是這樣的:
最左側是列表,點擊列表項可查看詳情,中間是詳情,詳情中有按鈕,點擊可加入購物車,最右側是購物車,購物車自動更新總數和總價.
使用create-react-app建立.
代碼以下:css

index.js:node

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:react

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:bootstrap

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.jsapp

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:dom

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;
相關文章
相關標籤/搜索