千锋教育-做有情怀、有良心、有品质的职业教育机构

当前位置:首页  >  关于学院  >  技术干货  >  html5技术干货  >  正文

redux+react-redux实现购物流程

来源:千锋教育
作者:qyf
关键词: 前端
2022-09-15
分享

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

  1. 菜单购物车实时中显示商品数量

  2. 在商品页面添加到购物车

  3. 进入购物车页面展示添加的商品

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

  // ...此处继续省略一万行代码

  }

  效果图

  菜单效果如下:

图片 3

  商品页面效果如下:

图片 2

图片 1

  结语

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

  · redux定义了初始数据state,并通过reducer提供了修改state的方法

  · react-redux利用Context共享redux中的数据(),并使用高阶组件(connect())把数据作为props传入组件

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

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

相关推荐

  • vuex中actions与mutations的区别 总体来说:actions 1、用于通过提交mutation改变数据 2、会默认将自身封装为一个Promise 3、可以包含任意的异步操作mutations 1、通过提交commit改变数据 2、只是一个单纯的函数 3、不要使用异步操作,异步操作会导致变量不能追踪
  • vuex数据丢失怎么解决 vuex的 store 中的数据是保存在运行内存中的,当页面刷新时,页面会重新加载 vue 实例,vuex 里面的数据就会被重新赋值,这样就会出现页面刷新vuex中的数据丢失的问题。 如何解决浏览器刷新数据丢失问题呢?
  • 说说vuex的管理操作或理解 vuex有一个仓库概念,将组件公共的state存储在仓库的state属性中,state是只读的,组件只能使用,不能直接修改,修改需要通过 仓库中的mutations模块来修改,这样的好处是 当数据修改便于溯源,且不会因为 多个组件 直接修改数据,导致 组件间数据的互相影响, 同时 当我们仓库中有一个state 数据需要请求 数据接口才能获取时,vuex 设计了一个action模块,在action模块中发送异步请求,得到数据后,提交mutation来修改state。
  • 说说Vuex的工作流程 我们将组件的公共状态定义在 vuex仓库的state中,state是只读的,无法直接修改,必须调动仓库中的某个mutation才能修改状态,getters可以理解为vuex中的计算属性,当我们在某个组件中使用vuex中的某个state时,不是直接使用原值,而是需要派生出一个新的值,就可以定义getters,可以在组件中获取。
  • vuex—个模块中改变state中数据,其他模块如何获取? 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
  • vuex的状态是怎样的,怎么改变状态 vuex的状态储存在仓库的state属性中,state是只读的,无法直接修改必须调用mutation才能修改,const store = new Vuex.Store({,// 在组件中直接出发mutaion,this.$store.commit('ADD_NUM', 10)// 或者助手函数 提交 mutation