使用react / redux调用的最大堆栈大小

时间:2017-06-08 19:38:47

标签: javascript reactjs redux

我想我知道问题是什么,但我不确定如何解决它。我希望我的州每次更新“动作/事件/无论什么”时都会更新。我正在尝试使用componentWillReceiveProps,但是就像我的代码由于某种原因进入一个永无止境的循环。

我已经在这个componentWillReceiveProps中放置了两个函数,每次发生某些事情时它们都会被更新。我将在这里发布代码:

仅供参考信息购物车是一个包含其中对象的对象。如果人们选择添加它们,它会获得更多项目,并且它也可以删除这些项目。

组件:

import React , { Component } from 'react';
import * as actions from '../../actions/cartActions';
import {Modal, Button} from 'react-bootstrap';
import {connect} from 'react-redux';
import _ from 'lodash';

class Cart extends Component {
  constructor() {
    super();
    this.state = {
      showModal: false,
    }

    this.getTotalAmount = this.getTotalAmount.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    console.log(this.props.price);
    this.getTotalAmount(nextProps.cart);
    this.getTotalQuantity(nextProps.cart);
    return true;
  }

  open() {
    this.setState({
      showModal: true
    });
  }

  close() {
    this.setState({
      showModal: false
    });
  }

  getTotalAmount(cart) {
    this.props.addTotal(cart);
  }

  getTotalQuantity(cart) {
    this.props.getTotalQuantity(cart);
  }

  onDelete(_id) {
    this.props.deleteCartItem(_id);
  }

  onIncrement(_id) {
    this.props.updateCart(_id, 1);
  }

  onDecrement(_id, quantity) {
    if(quantity > 1) {
      this.props.updateCart(_id, -1)
    }
  }

  renderCart() {
    if(Object.keys(this.props.cart).length > 0) {
      const cartItemList = _.map(this.props.cart, (cartItem) => {
        return (
          <div key={cartItem._id} className="panel-body">
            <div className="well">
              <div className="row">
                <div className="col-xs-12 col-sm-2">
                  <h6>{cartItem.title}</h6><span>    </span>
                </div>
                <div className="col-xs-12 col-sm-2">
                  <h6>usd. {cartItem.price}</h6>
                </div>
                <div className="col-xs-12 col-sm-2">
                  <h6>qty. <label className="label label-success">{cartItem.quantity}</label></h6>
                </div>
                <div className="col-xs-6 col-sm-4">
                  <div className="btn-group" role="group">
                    <button
                      onClick={this.onDecrement.bind(this, cartItem._id, cartItem.quantity)}
                      className="btn btn-default btn-sm"
                    >-</button>
                    <button
                      onClick={this.onIncrement.bind(this, cartItem._id)}
                      className="btn btn-default btn-sm"
                    >+</button>
                    <span>     </span>
                    <button onClick={this.onDelete.bind(this, cartItem._id)} className="btn btn-danger btn-sm">Delete</button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        );
      });
      return (
        <div className="panel-group">
          <div className="panel panel-primary">
            <div className="panel-heading">Cart</div>
            {cartItemList}
            <div className="row panel-body">
              <div className="col-xs-12">
                <h6>Total amount: {this.state.price.total}</h6>
                <button onClick={this.open.bind(this)} className="btn btn-success btn-sm">
                  PROCEED TO CHECKOUT
                </button>
              </div>
            </div>
            <Modal show={this.state.showModal} onHide={this.close.bind(this)}>
              <Modal.Header closeButton>
                <Modal.Title>Thank you!</Modal.Title>
              </Modal.Header>
              <Modal.Body>
                <h6>Your order has been saved</h6>
                <p>You will receive an email confirmation</p>
              </Modal.Body>
              <Modal.Footer>
                <div className="col-xs-6">
                  <h6>total $:</h6>
                </div>
                <Button onClick={this.close.bind(this)}>Close</Button>
              </Modal.Footer>
            </Modal>
          </div>
        </div>
      );
    } else {
      return (
        <div></div>
      );
    }
  }
  render() {

    return (
      <div>
        {this.renderCart()}
      </div>
    );
  }
}

function mapStateToProps(state){
  return {
    cart: state.cart,
    price: state.price
  };
}

export default connect(mapStateToProps, actions)(Cart);

行动:

export function addTotal(cart) {
  return {
    type: "ADD_TOTAL_PRICE",
    payload: cart
  }
}
export function getTotalQuantity(cart) {
  return {
    type: "ADD_QUANTITY",
    payload: cart
  }
}

减速器:

import _ from 'lodash';

export default function(state = [], action) {
  switch(action.type) {
    case "ADD_TOTAL_PRICE":
    let totalAmount = _.map(action.payload, (item) => {
      return item.quantity * item.price;
    }).reduce(function(a, b) {
      return a + b;
    }, 0).toFixed(2);
    return {...state, total: totalAmount}
    break;
    case "ADD_QUANTITY":
    let totalQuantity = _.map(action.payload, (item) => {
      return item.quantity;
    }).reduce(function(a, b) {
      return a + b;
    }, 0);
    return {...state, quantity: totalQuantity};
  }
  return state;
}

1 个答案:

答案 0 :(得分:0)

当您在run keyword if testcase=abc.robot 中进行函数调用时,通常需要在它们周围设置条件逻辑,这样只有在特定道具实际发生变化时才会调用它们。通常,这看起来像:

componentWillReceiveProps

在您的情况下,每次组件收到任何道具时,您都会调度Redux操作,该调度会导致React重新渲染,并重复循环。