Justin
Justin

Reputation: 151

× TypeError: Cannot destructure property 'xxx' of 'Object(...)(...)' as it is undefined

I am learning react redux, but I am facing this problem,

when I dispatch the 'remove' action

action

export const remove = () => ({
    type: REMOVE
})

in reducer inside switch statement

case REMOVE:
      return console.log("removed");

      break;

And I use it here on the remove button

import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { increase, decrease, remove } from "./../actions";

const CartItem = ({ img, title, price, amount }) => {
  const dispatch = useDispatch();

  const removeItem = () => {
    dispatch(remove());
  };

  return (
    <div className="cart-item">
      <img src={img} alt={title} />
      <div>
        <h4>{title}</h4>
        <h4 className="item-price">${price}</h4>
        {/* remove button */}
        <button className="remove-btn" onClick={removeItem}>
          remove
        </button>
      </div>
      <div>
        {/* increase amount */}
        <button className="amount-btn">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
            <path d="M10.707 7.05L10 6.343 4.343 12l1.414 1.414L10 9.172l4.243 4.242L15.657 12z" />
          </svg>
        </button>
        {/* amount */}
        <p className="amount">{amount}</p>
        {/* decrease amount */}
        <button className="amount-btn">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
            <path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z" />
          </svg>
        </button>
      </div>
    </div>
  );
};

export default CartItem;

the action just console logs, when I click the remove button, it logs 'removed' and then I get this error

TypeError: Cannot destructure property 'cart' of 'Object(...)(...)' as it is undefined.
CartContainer
E:/React_Projects/Redux-demo/starter-project-redux-tutorial-cart-master/src/components/CartContainer.js:6
  3 | import CartItem from "./CartItem";
  4 | import { clearCart } from "./../actions";
  5 | const CartContainer = () => {
> 6 |   const { cart, total } = useSelector((state) => state);
  7 |   const dispatch = useDispatch();
  8 |   
  9 |   const handleClick = () => {

I have used the initial state in my reducer file

import { CLEAR_CART, DECREASE, INCREASE, REMOVE } from "./actions";
// items
import cartItems from "./cart-items";

//initial store
const initialStore = {
    cart: cartItems,
    total: 1487.00,
    amount: 5,
  };

const reducer = (state = initialStore, action) => {
  switch (action.type) {

I don't know what the error means. Can someone explain and show me a solution.

Upvotes: 0

Views: 3375

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42218

The error is created by this:

case REMOVE:
    return console.log("removed");

    break;

You are returning nothing, when you need to be returning the state. So after the remove function is called and the state is set to nothing (undefined), functions which select from the state will throw errors because the state no longer exists. That’s why an error is thrown here:

const { cart, total } = useSelector((state) => state);

The error says that you can’t get the property “cart” from state because state is undefined.

You need to change your reducer so that it returns a valid state after every action. Eventually you’ll want to actually remove something, but for now this will work:

case REMOVE:
    console.log("removed");
    return state;

Upvotes: 1

Related Questions