1

I'm pretty sure that I don't use correctly useReducer there is an example :

**//My array with some items**    
const items = [
        {
          id: 0,
          title: "Cidre Doux",
          img:
            "img",
          type: "doux",
        },
        {
          id: 1,
          title: "Cidre demi-doux",
          img:
            "img",
          type: "demi-doux",
        },
   ]

**//UseState for passing category in dispatch**

const [categoryItem, setCategoryItem] = useState("");

**//useReducer**

const [state, dispatch] = useReducer(reducer, items);
  function reducer(state, action) {
    switch (action.type) {
      case "all":
        return [...items];

      case categoryItem:
        return items.map((item) =>
          item.type === categoryItem ? { ...item } : null
        );

      default:
        throw new Error();
    }
  }

**//function onClick**

  const dispatchCategory = (category) => {
    setCategoryItem(category);
    dispatch({ type: category });
  };

{...}

//Return

<button onClick={() => { dispatchCategory("doux");}}> Doux </button>

{...}

//My map

{state.map((item) => {
          if (item != null) {
            return <ShopCardItem key={item.id} {...item} />;
          } else {
            return "";
          }
        })}

In my reducer I use items and not the state because i have severals button for finding some category objets. If i use the state i can't get all items after clicking on a button.

There is an exemple if i use state in the function reducer:

Step: one, click on "all" => all items,

Step: two, click on "doux" => doux items,

Step :three, click on "all" again, only get doux items.

How can i resolve this problem ?

Ty very much !

1 Answers1

0

What you are doing here doesn't make sense. Your items are a constant. Your selected category is stored via useState (not stored in the reducer state). Why do you need the reducer?

Your reducer violates some of the fundamental principles of a reducer, like relying on an external state. The good news is that your component is easy to fix because the reducer can pretty much be be totally deleted. The logic that we want to keep is how to derive the current items from the category state. This list of filtered items is a variable that is derived from state. It does not need to be stored in state itself.

We look at categoryItem. If it's blank, the currentItems is all of the items, if it's a category, the currentItems are the items that match the category. I'm going to use "" to represent all instead of "all" since the initial value of your useState is "". Whatever you use, be consistent.

const currentItems = categoryItem === "" ? items : items.filter( item => item.type === categoryItem );

That's it. So now delete the entire useReducer. When you map the items, instead of state.map it's now currentItems.map. You can delete your dispatchCategory function too. Instead of dispatchCategory("doux") use setCategoryItem("doux").

Linda Paiste
  • 38,446
  • 6
  • 64
  • 102