Redux案例(巩固)

258 阅读8分钟

笔记来源:拉勾教育 - 大前端就业集训营

文章内容:学习过程中的笔记、感悟、和经验

提示:项目实战类文章资源无法上传,仅供参考

Redux案例

课程提供:

  • shoppingCart - 静态资源
  • shoppingCartService - 服务端项目,本地启动即可

项目搭建

  1. 命令行创建项目:create-react-app 项目名
  2. 安装费服务端项目依赖:npm i
  3. 启动服务端:npm start
  4. 初始化项目:清理我们不需要的文件、修改代码、创建我们需要的文件结构
  5. 创建组件并引用:商品列表组件、购物车列表组件(使用类组件)
  6. 使用结构:使用课程提供的HTML文件中的文件结构复制给两个组件
  7. 引入CSS文件:引入课程提供的CSS文件
  8. 引入图片:使用课程提供的资源文件,添加到项目中

R7XF9s.png

// src/components/list.js  商品列表组件,直接使用提供的HTML,后期更改

import React, { Component } from 'react'

// 商品列表
export class List extends Component {
  render() {
    return (
      <>
        <section class='container content-section'>
          <h2 class='section-header'>商品列表</h2>
          <div class='shop-items'>
            <div class='shop-item'>
              <img class='shop-item-image' src='images/01.webp' alt='' />
              <span class='shop-item-title'>
                小户型简约现代网红双人三人客厅科技布免洗布艺
              </span>
              <div class='shop-item-details'>
                <span class='shop-item-price'>¥1020</span>
                <button class='btn btn-primary shop-item-button' type='button'>
                  加入购物车
                </button>
              </div>
            </div>
            <div class='shop-item'>
              <img class='shop-item-image' src='images/02.webp' alt='' />
              <span class='shop-item-title'>11全网通4G手机官方iPhonexr</span>
              <div class='shop-item-details'>
                <span class='shop-item-price'>¥4758</span>
                <button class='btn btn-primary shop-item-button' type='button'>
                  加入购物车
                </button>
              </div>
            </div>
            <div class='shop-item'>
              <img class='shop-item-image' src='images/03.webp' alt='' />
              <span class='shop-item-title'>
                潮休闲网红小西服套装英伦风春装
              </span>
              <div class='shop-item-details'>
                <span class='shop-item-price'>¥59</span>
                <button class='btn btn-primary shop-item-button' type='button'>
                  加入购物车
                </button>
              </div>
            </div>
            <div class='shop-item'>
              <img class='shop-item-image' src='images/04.webp' alt='' />
              <span class='shop-item-title'>夏新27英寸超薄曲面高清电脑</span>
              <div class='shop-item-details'>
                <span class='shop-item-price'>¥369</span>
                <button class='btn btn-primary shop-item-button' type='button'>
                  加入购物车
                </button>
              </div>
            </div>
          </div>
        </section>
      </>
    )
  }
}

export default List
// src/components/cart.js  购物车组件,直接使用提供的HTML,后期更改

import React, { Component } from 'react'

// 购物车
export class Cart extends Component {
  render() {
    return (
      <>
        <section class='container content-section'>
          <h2 class='section-header'>购物车</h2>
          <div class='cart-row'>
            <span class='cart-item cart-header cart-column'>商品</span>
            <span class='cart-price cart-header cart-column'>价格</span>
            <span class='cart-quantity cart-header cart-column'>数量</span>
          </div>
          <div class='cart-items'>
            <div class='cart-row'>
              <div class='cart-item cart-column'>
                <img
                  class='cart-item-image'
                  src='images/01.webp'
                  width='100'
                  height='100'
                  alt=''
                />
                <span class='cart-item-title'>
                  小户型简约现代网红双人三人客厅科技布免洗布艺
                </span>
              </div>
              <span class='cart-price cart-column'>¥1020</span>
              <div class='cart-quantity cart-column'>
                <input class='cart-quantity-input' type='number' />
                <button class='btn btn-danger' type='button'>
                  删除
                </button>
              </div>
            </div>
            <div class='cart-row'>
              <div class='cart-item cart-column'>
                <img
                  class='cart-item-image'
                  src='images/02.webp'
                  width='100'
                  height='100'
                  alt=''
                />
                <span class='cart-item-title'>11全网通4G手机官方iPhonexr</span>
              </div>
              <span class='cart-price cart-column'>¥4758</span>
              <div class='cart-quantity cart-column'>
                <input class='cart-quantity-input' type='number' />
                <button class='btn btn-danger' type='button'>
                  删除
                </button>
              </div>
            </div>
          </div>
          <div class='cart-total'>
            <strong class='cart-total-title'>总价</strong>
            <span class='cart-total-price'>¥39.97</span>
          </div>
        </section>
      </>
    )
  }
}

export default Cart
// src/components/App.js  根组件,引入两个子组件

import Cart from './cart'
import List from './list'

// app根组件
function App() {
  return (
    <div>
      {/* 商品列表 */}
      <List />
      {/* 购物车 */}
      <Cart />
    </div>
  )
}

export default App

搭建redux工作流

  • 安装redux、react-redux、redux-saga、redux-actions依赖:
    • npm i redux react-redux redux-saga redux-actions -D
  • 新建store目录,存放redux相关文件
  • 创建action(指令)、reducer、saga目录和index.js(store)文件
  • 创建store仓库,并创建reducer(合并 - 不允许为空,先创建一个)
  • 将store传递给App组件
  • 组件接收reducer
// src/store/index.js  创建store

// import { createStore } from 'redux'
import rootReducer from './reducer/rootReducer'

// 创建 store 仓库
const store = createStore(rootReducer)

export default store
// src/store/reducer/rootReducer.js  创建文件合并 reducer

import { combineReducers } from 'redux'
import listReducer from './listReducer'

// reducer 合并
const rootReducer = combineReducers({
  // 商品列表
  list: listReducer,
})

export default rootReducer
// src/store/reducer/listReducer.js  创建商品列表 reducer

import { handleActions } from 'redux-actions'

// 商品列表初始数据
const list = []

// 商品列表 reducer
const listReducer = handleActions({}, list)

export default listReducer
// src/index.js  入口文件获取 store 并向下传递

import React from 'react'
import ReactDOM from 'react-dom'
import App from './components/App'
import { Provider } from 'react-redux'
import './style.css'
import store from './store'

ReactDOM.render(
  // 传递 store
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)
// src/components/list.js  组件尝试获取状态

import React, { Component } from 'react'
import { connect } from 'react-redux'

// 商品列表
export class List extends Component {
  render() {
    // 打印状态看一下
    console.log(this.props)
    return (
      <>
        <section className='container content-section'>
          <h2 className='section-header'>商品列表</h2>
          <div className='shop-items'>
            <div className='shop-item'>
              <img className='shop-item-image' src='images/01.webp' alt='' />
              <span className='shop-item-title'>
                小户型简约现代网红双人三人客厅科技布免洗布艺
              </span>
              <div className='shop-item-details'>
                <span className='shop-item-price'>¥1020</span>
                <button
                  className='btn btn-primary shop-item-button'
                  type='button'>
                  加入购物车
                </button>
              </div>
            </div>
            <div className='shop-item'>
              <img className='shop-item-image' src='images/02.webp' alt='' />
              <span className='shop-item-title'>
                11全网通4G手机官方iPhonexr
              </span>
              <div className='shop-item-details'>
                <span className='shop-item-price'>¥4758</span>
                <button
                  className='btn btn-primary shop-item-button'
                  type='button'>
                  加入购物车
                </button>
              </div>
            </div>
            <div className='shop-item'>
              <img className='shop-item-image' src='images/03.webp' alt='' />
              <span className='shop-item-title'>
                潮休闲网红小西服套装英伦风春装
              </span>
              <div className='shop-item-details'>
                <span className='shop-item-price'>¥59</span>
                <button
                  className='btn btn-primary shop-item-button'
                  type='button'>
                  加入购物车
                </button>
              </div>
            </div>
            <div className='shop-item'>
              <img className='shop-item-image' src='images/04.webp' alt='' />
              <span className='shop-item-title'>
                夏新27英寸超薄曲面高清电脑
              </span>
              <div className='shop-item-details'>
                <span className='shop-item-price'>¥369</span>
                <button
                  className='btn btn-primary shop-item-button'
                  type='button'>
                  加入购物车
                </button>
              </div>
            </div>
          </div>
        </section>
      </>
    )
  }
}

// 获取状态
const data = state => ({
  list: state.list,
})

export default connect(data)(List)

展示商品列表数据

需要安装axios

创建指令 - 创建reducer - 合并reducer(已实现)- 创建saga中间件 - 创建saga - 合并saga - 组件触发指令

  • 需要准备两个action指令,并且书写saga中间件拦截指令进行数据请求
  • 组件需要获取指令和名称
  • 组件挂载完成后立即自动获取数据
  • 引入并创建saga中间件,合并需要使用的saga,并让它运行起来
  • 使用接口文档查看接口信息
  • 组件获取数据后进行遍历绑定数据
// src/store/action/listAction.js  新建文件 - 创建指令

import { createAction } from 'redux-actions'

// 获取商品列表
export const loadList = createAction('loadList')
// 保存商品列表
export const loadList_save = createAction('loadList_save')
// src/store/reducer/listReducer.js  书写保存商品列表指令逻辑

import { handleActions } from 'redux-actions'
import { loadList_save } from '../action/listAction'

// 商品列表初始数据
const list = []

// 商品列表 reducer
const listReducer = handleActions(
  {
    // 保存商品列表
    [loadList_save]: (state, action) => action.payload,
  },
  list
)

export default listReducer
// src/store/saga/rootSage.js  新建文件 - saga合并

import { all } from 'redux-saga/effects'
import listSaga from './listSaga'

// 合并saga
export default function* rootSage() {
  yield all([listSaga()])
}
// src/store/saga/listSaga.js  新建文件 - 创建list相关saga

import { takeEvery, put } from 'redux-saga/effects'
import { loadList_save } from '../action/listAction'
import axios from 'axios'

// 拦截获取列表指令后回调函数
function* handelLoadList() {
  const { data } = yield axios.get('http://localhost:3005/goods')
  yield put(loadList_save(data))
}

// 拦截指令
export default function* listSaga() {
  // 拦截获取商品列表指令
  yield takeEvery('loadList', handelLoadList)
}
// src/store/index.js  store添加中间件

import { createStore, applyMiddleware } from 'redux'
import rootReducer from './reducer/rootReducer'
import createSaga from 'redux-saga'
import rootSage from './saga/rootSage'

// 创建saga
const saga = createSaga()

// 创建 store 仓库,使用 saga 中间件
const store = createStore(rootReducer, applyMiddleware(saga))

// 执行saga中间件
saga.run(rootSage)

export default store
// src/components/list.js  list组件挂载后触发指令获取数据,并遍历数据

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import * as listAction from '../store/action/listAction'

// 商品列表
export class List extends Component {
  // 钩子 - 挂载完成后获取商品列表
  componentDidMount() {
    this.props.loadList()
  }
  render() {
    return (
      <>
        <section className='container content-section'>
          <h2 className='section-header'>商品列表</h2>
          <div className='shop-items'>
            {/* 遍历商品列表 */}
            {this.props.list.map(item => (
              <div key={item.id} className='shop-item'>
                <img
                  className='shop-item-image'
                  // 商品图片通过接口获得
                  src={`http://localhost:3005${item.thumbnail}`}
                  alt=''
                />
                <span className='shop-item-title'>{item.title}</span>
                <div className='shop-item-details'>
                  <span className='shop-item-price'>¥{item.price}</span>
                  <button
                    className='btn btn-primary shop-item-button'
                    type='button'>
                    加入购物车
                  </button>
                </div>
              </div>
            ))}
          </div>
        </section>
      </>
    )
  }
}

// 获取状态
const data = state => ({
  list: state.list,
})
// 获取指令
const action = dispatch => ({
  ...bindActionCreators(listAction, dispatch),
})

export default connect(data, action)(List)

将商品加入购物车

创建指令 - 创建reducer - 合并reducer - 创建saga中间件 - 创建saga - 合并saga - 组件触发指令

  • 接口信息查看文档
  • list组件触发添加购物车指令,购物车组件获取购物车列表
  • 添加时需要进行判断,当前购物车数据是否已经存在这个商品,没有则添加,有则让数量+1
// src/store/action/cartAction.js  新建文件 - 创建指令(购物车相关)

import { createAction } from 'redux-actions'

// 购物车添加商品
export const addCart = createAction('addCart')
// 添加商品后保存到本地
export const addCart_save = createAction('addCart_save')
// src/store/reducer/cartReducer.js  新建文件 - 创建购物车reducer

import { handleActions } from 'redux-actions'
import { addCart_save } from '../action/cartAction'

// 购物车初始状态
const cart = []

// 向本地购物车添加数据
const addCart_save_handle = (state, action) => {
  const newState = JSON.parse(JSON.stringify(state))
  const my = newState.find(item => item.id === action.payload.id)
  if (my) {
    my.count += 1
  } else {
    newState.push(action.payload)
  }
  return newState
}

const cartReducer = handleActions(
  {
    // 向本地购物车添加数据
    [addCart_save]: addCart_save_handle,
  },
  cart
)

export default cartReducer
// src/store/reducer/rootReducer.js  合并reducer

import { combineReducers } from 'redux'
import cartReducer from './cartReducer'
import listReducer from './listReducer'

// reducer 合并
const rootReducer = combineReducers({
  // 商品列表
  list: listReducer,
  cart: cartReducer,
})

export default rootReducer
// src/store/saga/cartSaga.js  新建文件 - 常见购物车相关saga

import axios from 'axios'
import { takeEvery, put } from 'redux-saga/effects'
import { addCart_save } from '../action/cartAction'

// 添加购物车指令拦截后回调函数
function* handleaddCart(action) {
  const { data } = yield axios.post('http://localhost:3005/cart/add', {
    gid: action.payload,
  })
  yield put(addCart_save(data))
}

// 拦截指令
export default function* cartSaga() {
  // 拦截添加购物车指令
  yield takeEvery('addCart', handleaddCart)
}
// src/store/saga/rootSage.js  合并saga

import { all } from 'redux-saga/effects'
import cartSaga from './cartSaga'
import listSaga from './listSaga'

// 合并saga
export default function* rootSage() {
  yield all([listSaga(), cartSaga()])
}
// src/components/list.js  list组件获取购物车相关指令,并在点击添加购物车按钮时触发指令

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import * as listAction from '../store/action/listAction'
import * as cartAction from '../store/action/cartAction'

// 商品列表
export class List extends Component {
  // 钩子 - 挂载完成后获取商品列表
  componentDidMount() {
    this.props.loadList()
  }
  render() {
    return (
      <>
        <section className='container content-section'>
          <h2 className='section-header'>商品列表</h2>
          <div className='shop-items'>
            {/* 遍历商品列表 */}
            {this.props.list.map(item => (
              <div key={item.id} className='shop-item'>
                <img
                  className='shop-item-image'
                  // 商品图片通过接口获得
                  src={`http://localhost:3005${item.thumbnail}`}
                  alt=''
                />
                <span className='shop-item-title'>{item.title}</span>
                <div className='shop-item-details'>
                  <span className='shop-item-price'>¥{item.price}</span>
                  <button
                    className='btn btn-primary shop-item-button'
                    type='button'
                    // 加入购物车按钮添加点击事件点击后触发指令
                    onClick={() => this.props.addCart(item.id)}>
                    加入购物车
                  </button>
                </div>
              </div>
            ))}
          </div>
        </section>
      </>
    )
  }
}

// 获取状态
const data = state => ({
  list: state.list,
})
// 获取指令
const action = dispatch => ({
  ...bindActionCreators(listAction, dispatch),
  // 将购物车相关指令也添加进来
  ...bindActionCreators(cartAction, dispatch),
})

export default connect(data, action)(List)
// src/components/cart.js  购物车组件获取数据和指令

import React, { Component } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import * as cartAction from '../store/action/cartAction'

// 购物车
export class Cart extends Component {
  render() {
    return (
      <>
        {/* 打印到页面看一下 */}
        <p>{JSON.stringify(this.props.cart)}</p>
        <section className='container content-section'>
          <h2 className='section-header'>购物车</h2>
          <div className='cart-row'>
            <span className='cart-item cart-header cart-column'>商品</span>
            <span className='cart-price cart-header cart-column'>价格</span>
            <span className='cart-quantity cart-header cart-column'>数量</span>
          </div>
          <div className='cart-items'>
            <div className='cart-row'>
              <div className='cart-item cart-column'>
                <img
                  className='cart-item-image'
                  src='images/01.webp'
                  width='100'
                  height='100'
                  alt=''
                />
                <span className='cart-item-title'>
                  小户型简约现代网红双人三人客厅科技布免洗布艺
                </span>
              </div>
              <span className='cart-price cart-column'>¥1020</span>
              <div className='cart-quantity cart-column'>
                <input className='cart-quantity-input' type='number' />
                <button className='btn btn-danger' type='button'>
                  删除
                </button>
              </div>
            </div>
            <div className='cart-row'>
              <div className='cart-item cart-column'>
                <img
                  className='cart-item-image'
                  src='images/02.webp'
                  width='100'
                  height='100'
                  alt=''
                />
                <span className='cart-item-title'>
                  11全网通4G手机官方iPhonexr
                </span>
              </div>
              <span className='cart-price cart-column'>¥4758</span>
              <div className='cart-quantity cart-column'>
                <input className='cart-quantity-input' type='number' />
                <button className='btn btn-danger' type='button'>
                  删除
                </button>
              </div>
            </div>
          </div>
          <div className='cart-total'>
            <strong className='cart-total-title'>总价</strong>
            <span className='cart-total-price'>¥39.97</span>
          </div>
        </section>
      </>
    )
  }
}

// 获取数据
const data = store => ({
  cart: store.cart,
})
// 获取指令
const action = dispatch => ({
  ...bindActionCreators(cartAction, dispatch),
})

export default connect(data, action)(Cart)

购物车列表展示

直接在上面创建文件中书写即可

两个指令:获取购物车列表数据,将数据同步到本地购物车列表中

reducer书写初始化reducer逻辑

saga添加一条拦截逻辑

购物车组件挂载后立即出发获取购物车列表数据

获取数据后遍历数据创建结构并绑定数据

从购物车删除商品

依旧直接在上面创建文件中书写即可

两个指令:删除商品,删除本地购物车中商品

点击删除按钮触发删除指令

saga添加拦截删除指令逻辑

服务器端删除商品后会把索引返回,我们直接使用这个索引删除本地购物车即可

更改购物车商品数量

逻辑同上

购物车商品数量发生变化触发修改指令

saga拦截指令后请求接口修改

修改后接口会给我们返回修改后的商品信息

同步到本地购物车中

更正视图图片显示问题

修改图片地址为服务器地址

计算商品总价

直接使用购物车商品数据,计算商品总价格

以上四个写在一块

// src/store/action/cartAction.js  添加指令

import { createAction } from 'redux-actions'

// 购物车添加商品
export const addCart = createAction('addCart')
// 添加商品后保存到本地
export const addCart_save = createAction('addCart_save')

// 获取购物车数据
export const loadcart = createAction('loadcart')
export const loadcart_save = createAction('loadcart_save')

// 删除商品
export const deletecart = createAction('deletecart')
export const deletecart_save = createAction('deletecart_save')

//  修改商品数量
export const alterCountCart = createAction('alterCountCart')
export const alterCountCart_save = createAction('alterCountCart_save')
// src/store/reducer/cartReducer.js  添加指令相关逻辑

import { handleActions } from 'redux-actions'
import {
  addCart_save,
  loadcart_save,
  deletecart_save,
  alterCountCart_save,
} from '../action/cartAction'

// 购物车初始状态
const cart = []

// 向本地购物车添加数据
const addCart_save_handle = (state, action) => {
  const newState = JSON.parse(JSON.stringify(state))
  const my = newState.find(item => item.id === action.payload.id)
  if (my) {
    my.count += 1
  } else {
    newState.push(action.payload)
  }
  return newState
}
// 删除商品
const deleteCart_save_handle = (state, action) => {
  const newState = JSON.parse(JSON.stringify(state))
  newState.splice(action.payload, 1)
  return newState
}
// 修改商品数量
const alterCountCart_save_handle = (state, action) => {
  const newState = JSON.parse(JSON.stringify(state))
  const my = newState.find(item => item.id === action.payload.id)
  my.count = action.payload.count
  return newState
}

const cartReducer = handleActions(
  {
    // 向本地购物车添加数据
    [addCart_save]: addCart_save_handle,
    [loadcart_save]: (state, action) => action.payload,
    // 删除商品
    [deletecart_save]: deleteCart_save_handle,
    // 修改商品数量
    [alterCountCart_save]: alterCountCart_save_handle,
  },
  cart
)

export default cartReducer
// src/store/saga/cartSaga.js  添加其他指令拦截saga逻辑

import axios from 'axios'
import { takeEvery, put } from 'redux-saga/effects'
import {
  addCart_save,
  loadcart_save,
  deletecart_save,
  alterCountCart_save,
} from '../action/cartAction'

// 添加购物车指令拦截后回调函数
function* handleaddCart(action) {
  const { data } = yield axios.post('http://localhost:3005/cart/add', {
    gid: action.payload,
  })
  yield put(addCart_save(data))
}

//拦截货物购物车商品指令后的回调函数
function* handleloadcart() {
  const { data } = yield axios.get('http://localhost:3005/cart')
  yield put(loadcart_save(data))
}

// 拦截删除购物车商品后的回调函数
function* handledeletecart(action) {
  const { data } = yield axios.delete('http://localhost:3005/cart/delete', {
    params: { cid: action.payload },
  })
  yield put(deletecart_save(data.index))
}

// 拦截修改商品数量指令的回调函数
function* handlealterCountCart(action) {
  const { data } = yield axios.put('http://localhost:3005/cart', {
    ...action.payload,
  })
  yield put(alterCountCart_save(data))
}

// 拦截指令
export default function* cartSaga() {
  // 拦截添加购物车指令
  yield takeEvery('addCart', handleaddCart)
  // 拦截获取购物车商品指令
  yield takeEvery('loadcart', handleloadcart)
  // 拦截删除商品指令
  yield takeEvery('deletecart', handledeletecart)
  // 拦截修改商品数量指令
  yield takeEvery('alterCountCart', handlealterCountCart)
}
// src/components/cart.js  购物车添加指令触发方法、计算总价等逻辑

import React, { Component } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import * as cartAction from '../store/action/cartAction'

// 购物车
export class Cart extends Component {
  // 钩子 - 挂载完成后获取购物车商品
  componentDidMount() {
    this.props.loadcart()
  }
  render() {
    // 商品数量修改事件
    const countChange = (id, e) => {
      this.props.alterCountCart({ cid: id, count: e.target.value })
    }
    // 计算商品总价
    const Totalprice = () => {
      return this.props.cart.reduce((total, item) => {
        return (total += item.price * item.count)
      }, 0)
    }
    return (
      <>
        <section className='container content-section'>
          <h2 className='section-header'>购物车</h2>
          <div className='cart-row'>
            <span className='cart-item cart-header cart-column'>商品</span>
            <span className='cart-price cart-header cart-column'>价格</span>
            <span className='cart-quantity cart-header cart-column'>数量</span>
          </div>
          <div className='cart-items'>
            {this.props.cart.map(item => (
              <div key={item.id} className='cart-row'>
                <div className='cart-item cart-column'>
                  <img
                    className='cart-item-image'
                    // 使用图片地址
                    src={`http://localhost:3005${item.thumbnail}`}
                    width='100'
                    height='100'
                    alt=''
                  />
                  <span className='cart-item-title'>{item.title}</span>
                </div>
                <span className='cart-price cart-column'>¥{item.price}</span>
                <div className='cart-quantity cart-column'>
                  <input
                    className='cart-quantity-input'
                    type='number'
                    value={item.count}
                    // 商品数量修改事件
                    onChange={e => countChange(item.id, e)}
                  />
                  <button
                    className='btn btn-danger'
                    type='button'
                    // 删除按钮点击事件
                    onClick={() => this.props.deletecart(item.id)}>
                    删除
                  </button>
                </div>
              </div>
            ))}
          </div>
          <div className='cart-total'>
            <strong className='cart-total-title'>总价</strong>
            {/* 直接调用方法计算总价 */}
            <span className='cart-total-price'>¥{Totalprice()}</span>
          </div>
        </section>
      </>
    )
  }
}

// 获取数据
const data = store => ({
  cart: store.cart,
})
// 获取指令
const action = dispatch => ({
  ...bindActionCreators(cartAction, dispatch),
})

export default connect(data, action)(Cart)