d-dripz
d-dripz

Reputation: 85

Use value from object in reducer

I have an object stored in my reducer:

editProductBasket: [{
    name: "roger",
    price: "12",
}],

And I'm trying to use the values in a different part of my with the following code:

function PhoneMockupEdit() {
  const [
    {
      editProductBasket: { name, price, description, quantity },
    },
    dispatch,
  ] = useStateValue();
return (
    <div className="phone__mockup">
      <h1>{name}<h2>
    </div>
  );
}

However, the data from the reducer is not being shown. Any ideas why?

Here is my StateProvider code:

import React, { createContext, useContext, useReducer } from "react";

// create the data layer
export const StateContext = createContext();

// Build a provider so we can wrap entire app inside of provider so we access data layer
export const StateProvider = ({ reducer, initialState, children }) => (
  <StateContext.Provider value={useReducer(reducer, initialState)}>
    {children}
  </StateContext.Provider>
);

// This is where we use it in a component
export const useStateValue = () => useContext(StateContext);

And here is my reducer code:

export const initialState = {
  editProductBasket: [],
 
};

function reducer(state, action) {
  console.log(action);
  switch (action.type) {

    case "SET_EDIT_PRODUCT":
      return {
        ...state,
        editProductBasket: [...state.editProductBasket, action.item],
      };

    default:
      return state;
  }
}
export default reducer;

Upvotes: 0

Views: 48

Answers (1)

Zachary Haber
Zachary Haber

Reputation: 11027

You were destructuring your state incorrectly.

The editProductBasket property is an array not an object, so you need to destructure off the first element of the array, rather than try and destructure the properties off of the array as a whole.

      const [
        {
          editProductBasket: [{ name, price, description, quantity }],
        },
        dispatch,
      ] = useStateValue();

const { createContext, useContext, useReducer } = React;

// create the data layer
const StateContext = createContext();

// Build a provider so we can wrap entire app inside of provider so we access data layer
const StateProvider = ({ reducer, initialState, children }) => (
  <StateContext.Provider value={useReducer(reducer, initialState)}>
    {children}
  </StateContext.Provider>
);

// This is where we use it in a component
const useStateValue = () => useContext(StateContext);

const initialState = {
  editProductBasket: [
    {
      name: 'roger',
      price: '12',
    },
  ],
};

function reducer(state, action) {
  console.log(action);
  switch (action.type) {
    case 'SET_EDIT_PRODUCT':
      return {
        ...state,
        editProductBasket: [...state.editProductBasket, action.item],
      };

    default:
      return state;
  }
}

function PhoneMockupEdit() {
  const [
    {
      editProductBasket: [{ name, price, description, quantity }],
    },
    dispatch,
  ] = useStateValue();
  return (
    <div className="phone__mockup">
      <h1>{name}</h1>
    </div>
  );
}

ReactDOM.render(
  <StateProvider reducer={reducer} initialState={initialState}>
    <PhoneMockupEdit />
  </StateProvider>,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"/>

Upvotes: 1

Related Questions