index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import "bootstrap/dist/css/bootstrap.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { Provider } from "react-redux";
import { createStore } from "redux";
import reducer from "./reducer";
const store = createStore(reducer);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
App.js
import React, { Component } from "react";
import "./App.css";
import Router from "./Router";
class App extends Component {
render() {
return (
<div className="App">
<div>
<h1>React-Redux Store</h1>
<h2>Welcome to the React Store</h2>
</div>
<Router />
</div>
);
}
}
export default App;
ShopHome.js
import React, { Component } from "react";
import { NavLink } from "react-router-dom";
import { connect } from "react-redux";
import { addToCart } from "./action_type";
class ShopHome extends Component {
render() {
return (
<div>
<table className="table">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Price</th>
<th>
<NavLink to="/myCart" exact activeStyle={{ color: "green" }}>
<a href="#">my cart</a>
</NavLink>
</th>
</tr>
</thead>
<tbody>
{this.props.items.map(item => {
return (
<tr key={item.id}>
<td>{item.name}</td>
<td>{item.description}</td>
<td>${item.price}</td>
<button onClick={this.props.addToCart(item.id)}>
add to cart
</button>
</tr>
);
})}
</tbody>
</table>
</div>
);
}
}
const mapStateToProps = state => {
return {
items: state.items
};
};
const mapDispatchToProps = dispatch => {
return {
addToCart: id => {
dispatch(addToCart(id));
}
};
};
export default connect(mapStateToProps, mapDispatchToProps)(ShopHome);
ShopCart.js
import React, { Component } from "react";
import { NavLink } from "react-router-dom";
import { connect } from "react-redux";
import { addQuantity } from "./action_type";
class ShopCart extends Component {
render() {
let addedItems = this.props.items.map(item => {
return (
<tr key={item.id}>
<td>{item.name}</td>
<td>
<NavLink to="/myCart">
<i
class="glyphicon glyphicon-plus-sign"
onClick={this.props.addQuantity(item.id)}
></i>
{item.quantity}
<i
class="glyphicon glyphicon-minus-sign"
onClick={this.props.handleSubtractQuantity(item.id)}
></i>
</NavLink>
</td>
<td>${item.price}</td>
</tr>
);
});
return (
<div>
<table className="table">
<thead>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
<th>
<NavLink to="/" exact activeStyle={{ color: "green" }}>
<a href="#">back to store</a>
</NavLink>
</th>
</tr>
</thead>
<tbody>{addedItems}</tbody>
</table>
</div>
);
}
}
const mapStateToProps = state => {
return {
items: state.addedItems
};
};
const mapDispatchToProps = dispatch => {
return { addQuantity: id => dispatch(addQuantity(id)) };
};
export default connect(mapStateToProps, mapDispatchToProps)(ShopCart);
reducer.js
const initialState = {
items: [
{
id: 1,
name: "apple",
description: "Eat One Every Day, may keep the doctor away",
price: 12
},
{
id: 2,
name: "grape",
description: "Wine is great, but grapes is better",
price: 11
},
{
id: 3,
name: "pineapple",
description: "enjoy but don`t forget to peer first",
price: 8
}
],
addedItems: []
};
const reducer = (state = initialState, action) => {
if (action.type === "ADD_TO_CART") {
let addedItem = state.items.find(item => item.id === action.id);
let existed_item = state.addedItems;
if (existed_item) {
addedItem.quantity++;
} else {
addedItem.quantity = 1;
}
return {
...state,
addItems: [...state.addedItems, addedItem]
};
}
if (action.type === "ADD_QUANTITY") {
let addedItem = state.items.find(item => item.id === action.id);
addedItem.quantity++;
}
return {
...state
};
};
export default reducer;
action_type.js
export const addToCart = id => {
return {
type: "ADD_TO_CART",
id
};
};
export const addQuantity = id => {
return {
type: "ADD_QUANTITY",
id
};
};
Router.js
import React from "react";
import { Switch, Route } from "react-router-dom";
import ShopHome from "./shopHome";
import ShopCart from "./shopCart";
import { BrowserRouter } from "react-router-dom";
const Router = () => {
return (
<BrowserRouter>
<Switch>
<Route exact path="/" component={ShopHome} />
<Route exact path="/myCart" component={ShopCart} />
</Switch>
</BrowserRouter>
);
};
export default Router;
大家好,我是React-redux的新手,我正在尝试建立一个购物车网站,我有一个购物车主页面,该页面托管在localhost:3000上,一旦我按了我的购物车,就会进行路由到/ myCart,但是,我的问题是当我选择商品并将其添加到购物车时,ShopCart组件中最新添加的商品将不会呈现在我的购物车中,我不确定我做错了什么,有人可以给我一个手?
理想情况下,我认为当我在ShopHome.js中单击“添加到购物车”时,将触发addToCart函数,然后通过调度程序,使用action.type =“ ADD_TO_CART”和id = item.id,然后在化简器中,我要选择的商品数量加1,但是,当我按添加到购物车并点击购物车时,什么也没添加。
答案 0 :(得分:1)
首先,您的减速器中有错字。
addItems: [...state.addedItems, addedItem]
应该是addedItems: [...state.addedItems, addedItem]
接下来,您应该重写ADD_TO_CART
的逻辑。
let existed_item = state.addedItems;
if (existed_item) {
addedItem.quantity++;
} else {
addedItem.quantity = 1;
}
您将existed_item
分配给state.addedItems
,这是一个数组,因此existed_item
将始终为true,它将尝试增加确实存在的属性。
相反,将existed_item = state.addedItems
更改为existed_item = state.addedItems.find(x=>x.id === action.id)
。如果该项目存在,则增加,否则,添加quantity = 1
。