我收到这个奇怪的错误,警告:在呈现不同的组件(Cart
)时无法更新组件(Connect(Cart)
).为了定位Cart
内部错误的setState()调用.我不知道真正的问题在哪里,是在cart.js中还是在cartActions.js中?Js使用了Redux Thunk,有时在一个动作创建者中有多个沮丧.先谢谢你.
Cart.js,
import { Component, Fragment } from "react";
import AppNavbar from './AppNavbar';
import { Card, CardText, CardBody, CardTitle, CardSubtitle, Button, Alert, Container } from 'reactstrap';
import PropTypes from 'prop-types';
import { connect }from 'react-redux';
import { getCart, deleteFromCart } from '../actions/cartActions';
import Checkout from "./Checkout";
import { checkout } from '../actions/orderActions';
class Cart extends Component {
/*state = {
loaded: false
}*/
constructor(props) {
super(props);
this.state = {
loaded: false
}
}
//this.state.loaded = false;
static propTypes = {
getCart: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool,
addToCart: PropTypes.func.isRequired,
deleteFromCart: PropTypes.func.isRequired,
user: PropTypes.object.isRequired,
cart: PropTypes.object.isRequired,
checkout: PropTypes.func.isRequired
}
getCartItems = async (id) => {
await this.props.getCart(id);
//this.state.loaded = true;
this.setState({
loaded: true
});
}
onDeleteFromCart = (id, itemId) => {
this.props.deleteFromCart(id, itemId);
}
render() {
const user = this.props.user;
if (this.props.isAuthenticated && !this.props.cart.loading && !this.state.loaded) {
this.getCartItems(user._id);
}
//Why bind this with multiple things below?
//<Button color="danger" onClick={this.onDeleteFromCart.bind(this, user._id, item.productId)}>Delete</Button>
return (
<div>
<AppNavbar />
{this.props.isAuthenticated ?
<Fragment>
{this.props.cart.cart ? null :
<Alert color="info" className="text-center">Your cart is empty!</Alert>
}
</Fragment>
: <Alert color="danger" className="text-center">Login to View!</Alert>
}
{this.props.isAuthenticated && !this.props.cart.loading && this.state.loaded && this.props.cart.cart ?
<Container>
<div className="row">
{this.props.cart.cart.items.map(item => (
<div className="col-md-4">
<Card>
<CardBody>
<CardTitle tag="h5">{item.name}</CardTitle>
<CardSubtitle tag="h6">USD {item.price}</CardSubtitle>
<CardText>Quantity - {item.quantity}</CardText>
<Button color="danger" onClick={this.onDeleteFromCart.bind(this, user._id, item.productId)}>Delete</Button>
</CardBody>
</Card>
<br />
</div>
))}
<div class="col-md-12">
<Card>
<CardBody>
<CardTitle tag="h5">Total Cost = USD {this.props.cart.cart.bill}</CardTitle>
<Checkout
user={user._id}
amount={this.props.cart.cart.bill}
checkout={this.props.checkout}
/>
</CardBody>
</Card>
</div>
</div>
</Container>
: null}
</div>
);
}
}
const mapStateToProps = state => ({
cart: state.cart,
isAuthenticated: state.auth.isAuthenticated,
user: state.auth.user
})
export default connect(mapStateToProps, {getCart, deleteFromCart, checkout})(Cart);
CartActions.js,
//import axios from "axios";
import axios from "../http-common";
import { GET_CART, ADD_TO_CART, DELETE_FROM_CART, CART_LOADING } from "./types";
import { returnErrors } from './errorActions';
export const getCart = (id) => (dispatch) => {
dispatch(setCartLoading());
axios.get(`/api/cart/${id}`)
.then(res => {
dispatch({
type: GET_CART,
payload: res.data
});
})
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status));
});
}
export const addToCart = (id, productId, quantity) => (dispatch) => {
axios.post(`/api/cart/${id}`, {productId, quantity})
.then(res => {
dispatch({
type: ADD_TO_CART,
payload: res.data
});
})
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status));
});
}
//My addition for testing below,
/*export const updateCart = (id) => (dispatch) => {
axios.put(`/api/cart/${id}`)
.then(res => {
dispatch({
type: UPDATE_CART,
payload: Promise.all([id, res.data])
});
})
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status));
});
}*/
export const deleteFromCart = (userId, itemId) => (dispatch) => {
axios.delete(`/api/cart/${userId}/${itemId}`)
.then(res => {
dispatch({
type: DELETE_FROM_CART,
payload: res.data
});
})
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status));
});
}
export const setCartLoading = () => {
return {
type: CART_LOADING
}
}