简体   繁体   中英

How to set initial state in store

So i am trying to get state from the app store, and pass that into my component to render, one such problem im having is that it seems to not know the initial state of the specific state i am trying to use, for instance, if the state has already loaded (the action has dispatched and returned data from the API) then this works fine, however on a fresh load where the action has yet to dispatch it seems that the state is undefined, I've tried a few different things to set the state initially but it doesnt seemingly work, no matter what i do the state seems to be undefined at a fresh load. In my store i have this:

const votdFromStorage = localStorage.getItem("votd")
  ? JSON.parse(localStorage.getItem("votd"))
  : { votd: { bible: "", verse: [], passage: "", chapter: "" } };

const initialState = {
  // verse of the day
  votd: votdFromStorage,
};

This says to see if their already exists an item in localStorage and if it does return it, else return an object that has some inital values, the error im getting specifically is that it cant read bible of undefined. And im receiving this error here in my home component

  const dispatch = useDispatch();
  const {
    votd: { bible, passage, verse, chapter },
    loading,
  } = useSelector((state) => state.votd);

  useEffect(() => {
    dispatch({ type: VOTD_REQUEST });
    dispatch(verseOfTheDay());
  }, [dispatch]);

Here I am using the useSelector hook to grab from the state the votd object. of which, it cannot find bible , I am assuming it'd also be unable to find the other values as well but bible is first. anyways, i believe the problem is how i am setting initial state of the votd object, i even tried to set the init state inside the reducer similar to the one you see in the store, but it still returns the same error.

here is the reducer:

export const votdReducer = (state = {}, action) => {
  switch (action.type) {
    case VOTD_REQUEST:
      return { ...state, loading: true };
    case VOTD_SUCCESS:
      return { loading: false, votd: action.payload };
    case VOTD_FAIL:
      return { ...state, loading: false, error: action.payload };
    default:
      return state;
  }
};

also to help here is the initial state set to the store

const initialState = {
  // verse of the day
  votd: votdFromStorage,
};

I think you need to put the initial vote in the initial reducer like what I did, you can get the idea. It just will solve the undefined problem.

const votdFromStorage = localStorage.getItem("votd")
  ? JSON.parse(localStorage.getItem("votd"))
  : {};    

const initialState = {
      // verse of the day
     votd: { bible: "", verse: [], passage: "", chapter: "" }
    }; 
  
    initialState.votd= {...initialState.votd,...votdFromStorage?.votd};

         export const votdReducer = (state = initialState , action) => {
          switch (action.type) {
            case VOTD_REQUEST:
              return { ...state, loading: true };
            case VOTD_SUCCESS:
              return { loading: false, votd: action.payload };
            case VOTD_FAIL:
              return { ...state, loading: false, error: action.payload };
            default:
              return state;
          }
        };

Edited...

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