Search code examples
javascriptreactjsreduxreact-reduxredux-thunk

Setting Initial State to response from API with REDUX


I'm having trouble getting my head around setting the api response to the initial state object.

I've tried using the useAsyncThunk as stated in the documentation, however the project I'm working on only lets me use redux-thunk.

The goal is to download the usernames from https://jsonplaceholder.typicode.com/users and use that to create an autofill input field that suggests usernames.


Solution

  • I don't understand why you want to initialise your usernames already as initialState. That's not how the redux pattern works. Normally, you initialise your store with reasonable empty states:

    const initialState = {
      loading: false,
      usernames: [],
    }
    
    const reducer = (state = initialState, action) => {
      switch (action.type) {
        case LOADING_USERNAMES: 
          return {
            ...state,
            loading: true,
          };
        case USERNAMES_LOADED:
          return {
            ...state,
            loading: false,
            usernames: action.payload.usernames,
          };
        default:
          return state;
      }    
    }
    
    export default reducer;
    

    And then you set up your thunks and plain actions:

    export const LOADING_USERNAMES = '[User] loading usernames';
    export const USERNAMES_LOADED = '[User] usernames loaded';
    
    export const loadingUsernames = () => ({
      type: LOADING_USERNAMES,
    });
    
    export const usernamesLoaded = (usernames) => ({
      type: USERNAMES_LOADED,
      payload: {
        usernames,
      }
    });
    
    const getUsernameList = () => (dispatch) => {
      dispatch(loadingUsernames()); // for the loading state
      return fetch('https://jsonplaceholder.typicode.com/users')
        .then(response => dispatch(usernamesLoaded(response.json())))
    

    And then in your useEffect hook wherever you want to initialize this list, you call the thunk:

    dispatch(getUsernameList());
    

    You can decide not to show anything as long as loading is true and no list is present, but in my opinion a good UI lets the user know that something is happening. Maybe I didn't understand your question properly, but this at least would be my approach.

    You state, that you want this for an autofill, so maybe don't show the form until your data is ready, or alternatively show a spinner.