我得到这个奇怪的错误,警告:无法更新一个组件(Connect(Cart)
),而渲染一个不同的组件(Cart
).要找到坏的setState()调用内Cart
.我不知道哪里是真正的问题,在Cart.js或cartActions.js?cartActions. js使用Redux Thunk,有时多dispacth在一个动作创建者.提前感谢.
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);
字符串
carts.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
}
}
型
1条答案
按热度按时间ttisahbt1#
问题
代码正在调度
getCart
操作,并在render
方法中排队状态更新。两者都是***无意的***副作用。字符串
解决方案
React渲染函数被认为是 * 纯同步 * 函数。使用
componentDidMount
和componentDidUpdate
生命周期方法将这些作为 * 故意的 * 副作用发出。范例:
型