Search code examples
reduxreact-reduxredux-thunk

get the same state for different requests


i have this action:

export const connectToServer = (url, config, method) => {
  return (dispatch) => {
    dispatch({type: CONNECTION_START});
    axios({
      method: method,
      url: url,
      data: config
    })
      .then((response) => {
        dispatch({type: CONNECTION_LOADING_SUCCESS, payload: response.data});
      })
      .catch((error) => {
        dispatch({type: CONNECTION_LOADING_ERROR, payload: error.response.data});
      })
  }
};

And 2 identical reducers:

const initialState = {
  data: null,
  isLoading: false,
  error: null
};

export const connectToServerReducer = (state = initialState, action) => {
  switch (action.type) {
    case CONNECTION_START :
      return {...state, isLoading: true};
    case CONNECTION_LOADING_SUCCESS :
      return {...state, isLoading: false, data: action.payload, error: null};
    case CONNECTION_LOADING_ERROR:
      return {...state, isLoading: false, data: null, error: action.payload};
    default :
      return state
  }
};

export const differentUrlConnectToServerReducerTest = (state = initialState, action) => {
  switch (action.type) {
    case CONNECTION_START :
      return {...state, isLoading: true};
    case CONNECTION_LOADING_SUCCESS :
      return {...state, isLoading: false, data: action.payload, error: null};
    case CONNECTION_LOADING_ERROR:
      return {...state, isLoading: false, data: null, error: action.payload};
    default :
      return state
  }
};

My store looks like this:

  const rootReducer = combineReducers({
  allUsersData: connectToServerReducer,
  testData: differentUrlConnectToServerReducerTest
});

const configureStore = () => createStore(rootReducer, applyMiddleware(thunk));

export default configureStore

Then i use redux hooks to get a state with data in my components

 const allUsersData = useSelector(state => state.allUsersData);
 const testData = useSelector(state => state.testData);
 const dispatch = useDispatch();

Finally i dispatch them

dispatch(connectToServer(`${BASE_URL}user/allUsersWithPets`, null, 'get'));
dispatch(connectToServer(`${BASE_URL}fakeUrl`, null, 'get'));

I receive a correct data in allUsersData, but also i receive it in testData but i should receive in testData an initial state(empty object), because url is a fake

Where am i wrong?


Solution

  • You need to separate the reducers, use different initial states for example:

    connectToServer.js
    connectToServerTest.js
    

    Or you can try to add the test object to the initial state of connectToServerReducer.(not a good solution though)

    const initialState = {
      data: null,
      testData: null,
      isLoading: false,
      error: null
    };
    

    Remember that arrays affections won't assign values but addresses, so the "data" array is the same array in both the connectToServerReducer and connectToServerReducerTest.

    Second problem, you are calling the same action name in both reducers, this causes them not only to share the same variable from the previous problem I told you, but they share the same value assigned to them as well. Just change them to:

    CONNECTION_TEST_LOADING_SUCCESS
    CONNECTION_TEST_LOADING_ERROR
    CONNECTION_TEST_START
    

    PS: instead of using:

    export const connectToServer = (url, config, method) => {
      return (dispatch) => {
       ...
      }
    }
    

    Use:

      export const connectToServer = (url, config, method) => (dispatch) => {
           ...
          }