Redux案例实现购物车
Posted 橘猫吃不胖~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redux案例实现购物车相关的知识,希望对你有一定的参考价值。
【Redux案例】实现购物车
1 效果说明
假设我在网购,有两个商品A、B,它们是独立的组件,当我想购买A商品时,我就进入A商品详情页将其添加到购物车,想购买B商品亦然。
初始页面:localhost:3000
点击A商品,进入A商品详情页面,localhost:3000/a
点击添加购物车,有相应的效果:
点击B商品,进入B商品详情页面,localhost:3000/b:
点击添加购物车,有如下效果:
点击删除可以删除任意商品:
在本案例中,购物车是一个共享组件,此时可以使用Redux对购物车实现统一管理。
2 实现代码
2.1 创建项目
使用WebStorm创建一个React项目,安装redux模块
npm install redux
项目的目录结构如下所示:
2.2 store.js
在该文件中主要通过createStore生成store,创建reducer函数,具体代码如下:
import createStore from "redux";
// 定义reducer函数,它有两个参数:state和action
// store是初始的状态,action是派发的动作,goods表示商品
const cartReducer = (state = goods: [], action) =>
switch (action.type)
case "add": // 添加购物车
// 将state中的所有属性遍历出来(只有goods)
// goods数组中遍历出来之前的商品,再把新的商品加进去
return ...state, goods: [...state.goods, action.good];
case "delete": // 从购物车中删除
// 获取要删除的商品的索引
let deleteGoodIndex = action.good.index;
// 遍历所有的商品信息,并且放在新数组中
let newGoods = [...state.goods];
// 将要删除的商品从该数组中删除
newGoods.splice(deleteGoodIndex, 1);
return ...state, goods: newGoods; // 删除商品之后的数组覆盖原数组
default:
return state;
// 创建store对象
let store = createStore(cartReducer);
export default store; // 导出
2.3 A.js
在该文件中主要编写商品A的购物页面,具体代码如下:
import store from "./store";
import React from "react";
// 创建类组件
class A extends React.Component
constructor(props)
super(props);
this.state =
// 设置当前的初始状态length为store的商品的数量
length: store.getState().goods.length
componentDidMount() // 页面加载完成后执行该函数
// 订阅store中state的变化,并返回一个可以取消订阅的对象
this.unSubscribe = store.subscribe(() => // state发生变化后,执行回调函数
this.setState(
length: store.getState().goods.length
)
)
componentWillUnmount()
this.unSubscribe(); // 组件卸载时取消订阅
render()
const length = this.state; // 将购买的商品的数量解析出来
return (
<div>
<h2>A商品详情页面</h2>
<p>当前购物车内商品数量:length</p>
/*点击按钮后派发add动作,将商品添加到购物车*/
<button onClick=() => store.dispatch(
type: "add",
good:
title: `商品$Date.now()`, // 将日期作为商品的编号
price: 100
)>添加购物车
</button>
</div>
)
export default A;
2.4 B.js
编写商品B的商品详情页面,与A.js相同,具体代码如下:
import store from "./store";
import React from "react";
class B extends React.Component
constructor(props)
super(props);
this.state =
length: store.getState().goods.length
componentDidMount()
this.unSubscribe = store.subscribe(() =>
this.setState(
length: store.getState().goods.length
)
)
componentWillUnmount()
this.unSubscribe();
render()
const length = this.state;
return (
<div>
<h2>B商品详情页面</h2>
<p>当前购物车内商品数量:length</p>
<button onClick=() => store.dispatch(
type: "add",
good:
title: `B商品$Date.now()`,
price: 150
)
>添加购物车
</button>
</div>
)
export default B;
2.5 Cart.js
购买商品时,我们不仅能看到商品数量在增加,同时我们也能看到自己买了哪个商品,以及将购买的商品删除,该文件主要实现这个功能,具体代码如下:
import store from "./store";
import React from "react";
class Cart extends React.Component
constructor(props)
super(props);
this.state =
goods: store.getState().goods // 获取当前购买的商品列表
componentDidMount() // 页面加载完成后执行该函数
this.unSubscribe = store.subscribe(() =>
// 当state发生变化时执行回调函数
this.setState(
goods: store.getState().goods
)
)
componentWillUnmount()
this.unSubscribe(); // 取消订阅
render()
const goods = this.state; // 将商品列表获取出来
return (
<ul>
/*将商品遍历出来并显示在页面上*/
goods.map((good, index) =>
return (
<li key=index>
/*good.title是在A.js和B.js中定义的商品名称*/
<span>good.title</span>
<button onClick=() => store.dispatch(
type: "delete",
good: index // 将当前要删除的商品的索引派给good
)>删除
</button>
</li>
)
)
</ul>
)
export default Cart;
2.6 App.js
在App.js中主要进行路由配置,代码如下:
import logo from './logo.svg';
import './App.css';
import NavLink, Route from "react-router-dom";
import B from "./components/B";
import A from "./components/A";
import Cart from "./components/Cart";
function App()
return (
<div className="App">
<header className="App-header">
<img src=logo className="App-logo" alt="logo"/>
<div>
<NavLink to="/a">A商品</NavLink>
<NavLink to="/b">B商品</NavLink>
</div>
<Route path="/a" component=A/>
<Route path="/b" component=B/>
<Cart/>
</header>
</div>
);
export default App;
2.7 index.js
由于使用了Navlink,因此需要用BrowserRouter组件将App包起来。
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import BrowserRouter from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
<App/>
</BrowserRouter>,
document.getElementById('root')
);
reportWebVitals();
以上是关于Redux案例实现购物车的主要内容,如果未能解决你的问题,请参考以下文章
React Redux:reducers 是不是应该包含任何逻辑