redux+react-redux实现购物流程

redux+react-redux实现购物流程

在电商项目的开发过程中,会涉及到商品的下单与购买流程,大概流程如下:

  1. 菜单购物车实时中显示商品数量
  2. 在商品页面添加到购物车
  3. 进入购物车页面展示添加的商品

以上3步涉及到三个组件:菜单组件、商品组件、购物车组件,也就是说我们的数据需要在这三个组件间进行数据交互,因为是使用react开发的项目,于是在项目中引入redux实现多组件间的数据共享,由于reactredux是两个独立产品,它们之间并没有直接的联系,所以需要使用react-reduxreact组件和redux数据时行关联。

redux不用多说,是一个状态管理工具,能够帮助我们实现数据的管理有更新。 react-redux利用Context高阶组件实现了数据共享与组件自动刷新的问题。

万事具备,只差代码

一、共享redux数据

  1. 先使用redux创建数据
    // reducer/index.js
    const initState = {
        cartlist:[]
    }
    function reducer(state=initState,action){
        switch(action.type){
            // 添加商品
            case 'ADD_TO_CART':
                // 返回一个新的State,这个state会自动覆盖store中的旧数据
                return {
                    cartlist: [action.goods, ...state.cartlist]
                }
            // 删除商品
            case 'REMOVE_FROM_CART':
                return {
                    cartlist: state.cartlist.filter(item => item.goods_id != action.goods_id)
                }
            // 修改数量
            case 'CHANGE_QTY':
                return {
                    cartlist: state.cartlist.map(item => {
                        if (item.goods_id === action.goods_id) {
                            item.goods_qty = action.goods_qty
                        }
                        return item;
                    })
                }
            // 清空商品
            case 'CLEAR_CART':
                return {
                    cartlist: []
                }
            default:
                return state;
                
        }
    }
    export default reducer;
    // store/index.js
    import {createStore} from 'redux';
    import reducer from './reducer'
    const store = createStore(reducer);
    export default store;
  1. 使用react-redux共享数据
    import React from 'react'
    import ReactDOM from 'react-dom'
    import {Provider} from 'react-redux'
    import store from './store'
​
    ReactDOM.render(
        <Provider store={store}>
            <App/>
        </Provider>,
        document.getElementById('app')
    )

二、react组件接收数据

  1. 菜单组件接收购物车商品数量
    const mapStateToProps = (state)=>{
        return {
            cartCount:state.cartlist.length
        }
    }
    @connect(mapStateToProps)
    class Menu extends React.Component {
        //...此处省略部分代码
    }
  1. 商品页面接收购物车商品列表以及添加到购物车的方法
    import {connect} from 'react-redux';
​
    @connect((state)=>({
        cartlist:state.cart.cartlist
    }),dispatch=>({
        add2cart(goods){
            dispatch({
                type:'ADD_TO_CART',
                goods
            })
        },
        changeQty(goods_id,goods_qty){
            dispatch({
                type:'CHANGE_QTY',
                goods_id,
                goods_qty
            })
        }
    }))
    class Goods extends Component{
        // ...此处省略一万行代码
    }
  1. 购物车页面展示商品以及实现删除、清空购物车、修改商品数量等操作
    @connect(({cart:{cartlist}})=>({
        cartlist,
        totalPrice:cartlist.reduce((prev,item,idx,arr)=>prev+item.goods_price*item.goods_qty,0)
    }),(dispatch)=>{
        return {
            removeCart(goods_id){
                dispatch({
                    type:'REMOVE_FROM_CART',
                    goods_id
                })
            },
            clearCart(){
                dispatch({
                    type:'CLEAR_CART',
                })
            },
            changeQty(goods_id,goods_qty){
                dispatch({
                    type:'CHANGE_QTY',
                    goods_id,
                    goods_qty
                })
            }
        }
​
    })
    class Cart extends Component{
        // ...此处继续省略一万行代码
    }

效果图

菜单效果如下:

商品页面效果如下:

结语

redux + react-redux实现了一个商品添加到购物车的完整流程,细心的小伙伴发现,redux与react-redux各自实现了不同的功能:

  • redux定义了初始数据state,并通过reducer提供了修改state的方法
  • react-redux利用Context共享redux中的数据(<Provider/>),并使用高阶组件connect())把数据作为props传入组件

其中的原理其实很简单,<Provider/>组件使用Context实现了跨组件间的数据共享,不管组件层级有多深都能直接获取的redux上的数据,而connect()高阶组件则通过props往React组件中传递redux数据,使用props的好处就是当redux数据有修改时(即props有修改)组件会自动刷新。

猜你喜欢

转载自blog.csdn.net/GUDUzhongliang/article/details/108580517