1

Just started to learn redux, I don't want to use react-redux right now, i'm just using redux. I'm trying to dispatch an action to fill the cards with numbers, I don't understand why it isn't working. when I dispatch in the store.js file it works but not in the Game component.

store.js :

import { createStore } from "redux";

const state = {
  cards: [],
  player: "mor",
  computer: { name: "computer", cards: [] },
};

const reducer = (state, action) => {
  switch (action.type) {
    case "SET_CARDS":
      return {
        ...state,
        cards: action.payload.initCards(),
      };
    default:
      break;
  }
};

const store = createStore(reducer, state);

export { store };

Game.js:

import React from "react";
import { useEffect } from "react";
import { store } from "./store";

const NUM_OF_CARDS = 52;
const MAX_CARD_VALUE = 13;

function Game() {
  //shuffle cards with Fisher Yates algorithm
  const shuffle = (array) => {
    for (let i = array.length - 1; i > 0; i--) {
      let j = Math.floor(Math.random() * (i + 1));
      [array[i], array[j]] = [array[j], array[i]];
    }
  };

  const setCards = {
    type: "SET_CARDS",
    payload: {
      initCards: () => {
        const cards = Array(NUM_OF_CARDS / MAX_CARD_VALUE)
          .fill(
            Array(13)
              .fill()
              .map((_, i) => i + 1)
          )
          .flat();
        shuffle(cards);
        return cards;
      },
    },
  };

  useEffect(() => {
    store.dispatch(setCards);
  }, []);

  return (
    <div>
      {store.getState().cards?.map((card) => (
        <div>{card}</div>
      ))}
    </div>
  );
}

export default Game;

index.js:

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { store } from "./store";

const render = () => ReactDOM.render(<App />, document.getElementById("root"));

store.subscribe(render);

render();

I get an error that I can't use the map function on cards... thanks.

1 Answer 1

2

According to the docs you should return initial state in your reducer if action.type is undefined.

When a store is created, Redux dispatches a dummy action to your reducer to populate the store with the initial state. You are not meant to handle the dummy action directly. Just remember that your reducer should return some kind of initial state if the state given to it as the first argument is undefined, and you're all set.

const reducer = (state, action) => {
  switch (action.type) {
    case "SET_CARDS":
      return {
        ...state,
        cards: action.payload.initCards(),
      };
    default:
      return state;
  }
};
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, one question, why would the state be undefined if I pass the initial state to createStore? I have an initial state...
@morh The initial state is not undefined but when redux dispatches the INIT action your reducer returns undefined. Look closely to your reducer and ask yourself what would it return if the action type is @INIT?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.