19.redux实现购物车
2020-05-22 本文已影响0人
__疯子__
redux官方文档 redux和react没有关系,redux可以在任何环境下运行
随着JavaScript
单页应用开发日趋复杂,JavaScript
需要管理比任何时候都要多的state
(状态)。 这些state
可能包括服务器响应、缓存数据、本地生成尚未持久化到服务器的数据,也包括UI
状态,如激活的路由,被选中的标签,是否显示加载动效或者分页器等等。
管理不断变化的state
非常困难。如果一个model
的变化会引起另一个model
变化,那么当view
变化时,就可能引起对应model
以及另一个model
的变化,依次地,可能会引起另一个view
的变化。直至你搞不清楚到底发生了什么。state
在什么时候,由于什么原因,如何变化已然不受控制。 当系统变得错综复杂的时候,想重现问题或者添加新功能就会变得举步维艰。
初始化项目目录
- src
- actions
- components
- CartList
- index.js
- index.js
- reducers
- App.js
- index.js
- store.js
1.使用redux
安装依赖cnpm i -D redux
数量增加或减少操作
1.新增文件src/actions/actionType.js
export default {
CART_ITEM_INCREMENT:'CART_ITEM_INCREMENT', //加
CART_ITEM_DECREMENT:'CART_ITEM_DECREMENT', //减
}
2.新增文件src/actions/cart.js
import actionType from './actionType'
//加
export const increment={
type:actionType.CART_ITEM_INCREMENT
};
//减
export const decrement={
type:actionType.CART_ITEM_DECREMENT
};
3.在src/components/CartList/index.js
使用上面定义的type
import {increment,decrement} from '../../actions/cart'
render() {
return (
<table>
<thead>
<tr>
<th>编号</th>
<th>商品名称</th>
<th>价格</th>
<th>数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{
this.state.cartList.map(item=>{
return(
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.title}</td>
<td>{item.price}</td>
<td> #upadte修改开始
<button onClick={()=>{
this.props.store.dispatch(decrement(item.id))
}}>-</button>
<span>{item.amount}</span>
<button onClick={()=>{
this.props.store.dispatch(increment(item.id))
}}>+</button>
</td>#update修改结束
<td></td>
</tr>
)
})
}
</tbody>
</table>
);
}
4.进行加减操作src/reducers/Cart.js
import actionType from '../actions/actionType'
... 中间内容不变
export default (state=initState,action)=>{
switch (action.type) {
case actionType.CART_ITEM_INCREMENT:
return state.map(item=>{
if(item.id===action.payload.id){
item.amount+=1;
}
return item;
});
case actionType.CART_ITEM_DECREMENT:
return state.map(item=>{
if(item.id===action.payload.id){
item.amount-=1;
}
return item;
});
default:
return state;
}
}
5.当数据有变化后执行渲染视图
getState=()=>{
this.setState({
cartList:this.props.store.getState().Cart
})
};
componentDidMount() {
this.getState();
this.props.store.subscribe(this.getState)
}
配置流程
1.src/actions/actionType.js
定义常量,这样不容易混乱
export default {
CART_ITEM_INCREMENT:'CART_ITEM_INCREMENT', //加
CART_ITEM_DECREMENT:'CART_ITEM_DECREMENT', //减
}
2.src/actions/index.js
//引用定义的type类型
import actionType from './actionType'
//加 按钮
export const increment = (id) => {
return {
type: actionType.CART_ITEM_INCREMENT,
payload: { //调用的时候需要使用payload.id
id
}
}
};
//减 按钮
//id:当前修改的是哪一个
export const decrement = (id) => {
return {
type: actionType.CART_ITEM_DECREMENT,
payload: {
id
}
}
};
3.src/reducers/Cart.js
//引用常量类型
import actionType from '../actions/actionType'
//定义初始化数据
const initState=[{
id:1,
title:"Apple",
price:888.66,
amount:10,
}];
/**
*
* @param state 当前的state 如果不传则为默认初始化数据
* @param action 传输 类型及数据 (type,payload)
* @return {{amount: number, price: number, id: number, title: string}[]}
*/
export default (state=initState,action)=>{
switch (action.type) {
case actionType.CART_ITEM_INCREMENT:
return state.map(item=>{//遍历当前state数据
if(item.id===action.payload.id){// 判断当前state中的数据和传输过来的数据id对应则amount++
item.amount+=1;
}
return item;
});
case actionType.CART_ITEM_DECREMENT:
return state.map(item=>{
if(item.id===action.payload.id){
item.amount-=1;
}
return item;
});
default:
return state;
}
}
4.src/reducers/index.js
//combineReducers 用来合并多个reducer 在外层就可以直接使用 store.getState().cart
import { combineReducers } from 'redux'
import Cart from './Cart'
export default combineReducers({
Cart
})
5.src/store.js
import {createStore} from 'redux';
import rootReducer from './reducers';
export default createStore(rootReducer);
6.src/components/CartList/index.js
import React, {Component} from 'react';
//引用action中的cart
import {increment,decrement} from '../../actions/cart'
//引用redux中的store (../../store已经导出store了,所以直接引用就可以)
import store from '../../store'
class Index extends Component {
constructor(props) {
super(props);
//本组件的默认数据
this.state={
cartList:[]
};
}
//获取store中的Cart数据并给当前组件的数据进行设置
getState=()=>{
this.setState({
cartList:store.getState().Cart
})
};
componentDidMount() {
this.getState();
//初始化数据
store.subscribe(this.getState)
}
render() {
return (
<table>
<thead>
<tr>
<th>编号</th>
<th>商品名称</th>
<th>价格</th>
<th>数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{/*遍历当前组件的数据*/}
{
this.state.cartList.map(item=>{
return(
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.title}</td>
<td>{item.price}</td>
<td>
{/*dispatch是自动生成,用来调用函数的 如果需要修改状态值,就必须使用dispatch来调用*/}
<button onClick={()=>{
store.dispatch(decrement(item.id))
}}>-</button>
<span>{item.amount}</span>
<button onClick={()=>{
store.dispatch(increment(item.id))
}}>+</button>
</td>
<td></td>
</tr>
)
})
}
</tbody>
</table>
);
}
}
export default Index;
7.src/components/index.js
//导出CartList组件
export {default as CartList} from './CartList'
8.src/App.js
import React, {Component} from 'react';
import {
CartList
} from "./componets";
class App extends Component {
render() {
return (
<div>
<CartList/>
</div>
);
}
}
export default App;
9.src/index.js
import React from 'react'
import {render} from 'react-dom'
import App from './App'
render(
<App/>,
document.getElementById("root")
);