简体   繁体   中英

How do I clear an array in the state of my Redux store?

I am building a small e-commerce shop and I am trying to clear my cart after a successful checkout. The cart contains cartItems which are stored in the Redux store. I am getting the console log in my function in the StripeCheckoutForm component and the action creator.

I am not seeing the console log for the reducer so I suspect something is wrong with my action creator. I am not sure about best practices concerning action creators. I was wondering when, why, and how to use dispatch in the action creator. The docs for Redux aren't exactly clear for me.

Here is my StripeCheckout:

import React, {Component} from 'react';
import { CardElement, injectStripe } from 'react-stripe-elements';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { clearCart } from '../actions/clearCartAction';
import getTotal from '../helpers/getTotalHelper';
import { Container, Col, Form, FormGroup, Input } from 'reactstrap';
import './StripeCheckoutForm.css';

const cardElement = {
  base: {
    color: '#32325d',
    width: '50%',
    lineHeight: '30px',
    fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
    fontSmoothing: 'antialiased',
    fontSize: '18px',
    '::placeholder': {
      color: '#aab7c4'
    }
  },
  invalid: {
    color: '#fa755a',
    iconColor: '#fa755a'
  }
};

const FIREBASE_FUNCTION = 'https://us-central1-velo-velo.cloudfunctions.net/charge/';

// Function used by all three methods to send the charge data to your Firebase function
async function charge(token, amount, currency) {
  const res = await fetch(FIREBASE_FUNCTION, {
      method: 'POST',
      body: JSON.stringify({
          token,
          charge: {
              amount,
              currency,
          },
      }),
  });
  const data = await res.json();
  data.body = JSON.parse(data.body);
  return data;
}

class CheckoutForm extends Component {
  constructor(props) {
    super(props);
    this.submit = this.submit.bind(this);
  }

  state = {
    complete: false
  }

  clearCartHandler = () => {
    console.log('clearCartHandler');
    this.props.onClearCart()
  }

  // User clicked submit
  async submit(ev) {
    console.log("clicked!")
    const {token} = await this.props.stripe.createToken({name: "Name"});
    const total = getTotal(this.props.cartItems);
    const amount = total; // TODO: replace with form data
    const currency = 'USD';
    const response = await charge(token, amount, currency);

    if (response.statusCode === 200) {
      this.setState({complete: true});
      console.log('200!!',response);
      this.clearCartHandler();

    } else {
      alert("wrong credit information")
      console.error("error: ", response);
    }
  }

  render() {

    if (this.state.complete) {
      return (
        <div>
          <h1 className="purchase-complete">Purchase Complete</h1>
          <Link to='/'>
            <button>Continue Shopping</button>
          </Link>
        </div>
      );
    }

    return ( 
      <div className="checkout-wrapper"> 
      <Container className="App">
        <h2 className='text-center'>Let's Checkout</h2>
          <Form className="form">
            <Col>
              <FormGroup>
                <Input
                  type="first name"
                  name="first name"
                  id="exampleEmail"
                  placeholder="first name"
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Input
                  type="last name"
                  name="last name"
                  id="exampleEmail"
                  placeholder="last name"
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Input
                  type="address"
                  name="address"
                  id="exampleEmail"
                  placeholder="address"
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Input
                  type="city"
                  name="city"
                  id="exampleEmail"
                  placeholder="city"
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Input
                  type="prefecture"
                  name="prefecture"
                  id="exampleEmail"
                  placeholder="prefecture"
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Input
                  type="zipcode"
                  name="zipcode"
                  id="exampleEmail"
                  placeholder="zipcode"
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Input
                  type="email"
                  name="email"
                  id="exampleEmail"
                  placeholder="myemail@email.com"
                />
              </FormGroup>
            </Col>
            <div className="card-element">
            <CardElement style={cardElement}/>
            </div>
          </Form>
        <button className="checkout-button" disabled={false} onClick={this.submit}>Submit</button>
      </Container>
      </div> 
    );
  }
}

const mapStateToProps = state => {
  return {
    cartItems: state.shoppingCart.cartItems
  }
}

const mapDispatchToProps = state => {
  return {
    onClearCart: () => (clearCart())
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(injectStripe(CheckoutForm)); 

Here is my action creator:

import { CLEAR_CART } from './types';

// export const clearCart = (dispatch)  => { 
//   console.log('clear_action')
//   dispatch({
//     type: CLEAR_CART,
//   })   
// } 

export function clearCart() {
  console.log('clear_action')
  return { 
    type: CLEAR_CART
  }
}

and finally my reducer:

import {ADD_TO_CART} from '../actions/types';
import {REMOVE_FROM_CART} from '../actions/types';
import {CLEAR_CART} from '../actions/types';

const initialState = {
  cartItems: [],
}

export default function(state = initialState, action) {
  switch(action.type) {
    case ADD_TO_CART:
    console.log('ADD_reducer');
      return {
        ...state,
        cartItems: [...state.cartItems, action.payload],
      }
    case REMOVE_FROM_CART:
    console.log('REMOVE_REDUCER', action.payload, state.cartItems);
      return {
        ...state,
        cartItems: state.cartItems.filter(item => item.id !== action.payload.id)
      }
    case CLEAR_CART:
    console.log('CLEAR_REDUCER');
      return {
        ...state,
        cartItems: []
      }
    default:
      return state;
  }
}

Action has to be dispatched like below. Let me know if it works

const mapDispatchToProps = (dispatch) => {
  return {
    onClearCart: () => (dispatch(clearCart()))
  }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM