我正在使用Redux制作一个简单的购物车应用程序。现在,每次我更改页面时,都会自动调用动作三次,其次数等于项的数量。如果我进入购物车页面,removeItems操作将被调用3次,所以到目前为止我还无法将商品添加到购物车中。这可能是关于路由器的问题,但我无法发现问题。谁能解释我的问题是什么?
Home.js
import React from 'react';
import { connect } from 'react-redux';
import { addToCart } from '../actions';
class Home extends React.Component {
handleClick = id => {
this.props.addToCart(id)
}
renderList = () => {
return this.props.cart.slice(0, 3).map(item => {
return (
<div className="card" key={item.id} style={{width: "200px", float: "left", marginRight: "20px"}}>
<div className="card-image">
<img src={item.imageUrl} alt={item.name} />
<span className="card-title">{item.name}</span>
<span to="/"
className="btn-floating halfway-fab waves-effect waves-light red"
onClick={this.handleClick(item.id)}
>
<i className="material-icons">add</i>
</span>
</div>
<div className="card-content">
<p>{item.desc}</p>
<p><b>${item.price}</b></p>
</div>
</div>
)
})
}
render() {
console.log(this.props.cart)
return (
<div className="container">
<h3>Home</h3>
<div className="box">
{this.renderList()}
</div>
</div>
)
}
}
const mapStateToProps = state => {
return { cart: state.cart.items }
}
const mapStateToDispatch = dispatch => {
return {
addToCart: (id) => { dispatch(addToCart(id)) }
}
}
export default connect(mapStateToProps, mapStateToDispatch)(Home);
Cart.js
import React from 'react';
import { connect } from 'react-redux';
import { removeItem } from '../actions';
class Cart extends React.Component {
handleClick = (id) => {
this.props.removeItem(id);
}
renderList = () => {
if (this.props.addedItems.length !== 0) {
return this.props.addedItems.map(item => {
return (
<li className="collection-item avatar" key={item.id}>
<div className="item-img">
<img src={item.imageUrl} alt={item.name} style={{width: "120px"}} />
</div>
<div className="item-desc">
<span className="title">{item.name}</span>
<p>{item.content}</p>
<p><b>${item.price}</b></p>
</div>
<button
className="waves-effect waves-light btn pink remove"
onClick={this.handleClick(item.id)}
>Remove</button>
</li>
)
})
}
else {
return <p>Nothing is in cart.</p>
}
}
render() {
return (
<div className="container">
<div className="cart">
<ul className="collection">
{this.renderList()}
</ul>
</div>
</div>
)
}
}
const mapStateToProps = state => {
return { addedItems: state.cart.addedItems }
}
const mapDispatchToProps = dispatch => {
return {
removeItem: (id) => {dispatch(removeItem(id))}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Cart);
Header.js
import React from 'react';
import { Link } from 'react-router-dom';
const Header = () => {
return (
<nav className="nav-wrapper">
<div className="container">
<Link to="/" className="brand-logo">Shopping</Link>
<ul className="right">
<li><Link to="/">Shop</Link></li>
<li><Link to="/cart">Cart</Link></li>
<li><Link to="/cart"><i className="material-icons">shopping_cart</i></Link></li>
</ul>
</div>
</nav>
)
}
export default Header;
减速器
import data from '../data.json';
import { ADD_TO_CART, REMOVE_FROM_CART } from "../actions/types";
const INITIAL_DATA = {
items: data,
addedItems: [],
total: 0
}
const cartReducer = (state = INITIAL_DATA, action) => {
switch(action.type) {
case ADD_TO_CART:
let addedItem = state.items.find(item => item.id === action.id);
let existedItem = state.addedItems.find(item => action.id ===item.id);
if (existedItem) {
addedItem.quantity += 1;
return {
...state,
total: state.total + addedItem.price
}
}
else {
addedItem.quantity = 1;
let newTotal = state.total + addedItem.price;
return {
...state,
addedItems: [...state.addedItems, addedItem],
total: newTotal
}
}
case REMOVE_FROM_CART:
let itemToRemove = state.addedItems.find(item => action.id === item.id);
let newItems = state.addedItems.filter(item => action.id !== item.id);
let newTotal = state.total - itemToRemove.price;
return {
...state,
addedItems: newItems,
total: newTotal
}
default:
return state;
}
}
export default cartReducer;
操作
import { ADD_TO_CART, REMOVE_FROM_CART } from "./types";
export const addToCart = (id) => {
return {
type: ADD_TO_CART,
id
}
}
export const removeItem = (id) => {
return {
type: REMOVE_FROM_CART,
id
}
}
App.js
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Header from './Header';
import Home from './Home';
import Cart from './Cart';
const App = () => {
return (
<BrowserRouter>
<div className="app">
<Header />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/cart" component={Cart} />
</Switch>
</div>
</BrowserRouter>
)
}
export default App;
答案 0 :(得分:1)
似乎您实际上在渲染组件时实际上都在调用单击处理程序,而不仅仅是传递处理程序功能,因此这就是多次触发操作的原因。
例如,在您的Home.js
组件中,将以下代码从以下位置更改:
<span to="/" className="btn-floating halfway-fab waves-effect waves-light red" onClick={this.handleClick(item.id)} >
收件人:
<span to="/" className="btn-floating halfway-fab waves-effect waves-light red" onClick={() => { this.handleClick(item.id); }} >
与Cart.js
上的相同内容,改为:
<button className="waves-effect waves-light btn pink remove" onClick={this.handleClick(item.id)}>Remove</button>
至:
<button className="waves-effect waves-light btn pink remove" onClick={() => {this.handleClick(item.id); }}>Remove</button>