Daniel Richter
Daniel Richter

Reputation: 858

How to handle multiple Requests with Redux (React Native) - without overwrite itself?

i have a default config, found through net search, and implement this in my App and it works. On my Homescreen the data is loaded and can be used. After this i need a second action which loads other data for another screen. But now is only one action available. First the data on homescreen is available and second screen get the same data, or second screen get the correct data and by switching back to homescreen there is the data from the second screen available. The Example from HomeScreen looks like:

action/index.js

export function fetchArticleDetails() {
  return apiAction({
    url: "requesturl",
    onSuccess: setArticleDetails,
    onFailure: () => console.log("Error occured loading articles"),
    label: FETCH_ARTICLE_DETAILS
  });
}

function setArticleDetails(data) {
  return {
    type: SET_ARTICLE_DETAILS,
    payload: data
  };
}

the reducer looks as follows

export default function(state = {}, action) {
  console.log("action type => ", action.type);
  switch (action.type) {
    case SET_ARTICLE_DETAILS:
      return { data: action.payload };
    case API_START:
      if (action.payload === FETCH_ARTICLE_DETAILS) {
        return {
          ...state,
          isLoadingData: true
        };
      }
    case API_END:
      if (action.payload === FETCH_ARTICLE_DETAILS) {
        return {
          ...state,
          isLoadingData: false
        };
      }
   ...

i thought, i can add a custom action with the same params as above now action/index.js added following

export function fetchPeopleList() {
  return apiAction({
    url: "http://wfmanager.de/appApi/2.0.0/getPeopleList/1",
    onSuccess: setPeopleList,
    onFailure: () => console.log("Error occured loading articles"),
    label: FETCH_PEOPLELIST
  });
}

function setPeopleList(data) {
  return {
    type: SET_PEOPLELIST,
    payload: data
  };
}

and reducer added following:

case SET_PEOPLELIST:
    return { data: action.payload };

case API_START:
    ....
    if (action.payload === FETCH_PEOPLELIST) {
      return {
        ...state,
        isLoadingData: true
      };
    }
    ....
case API_END:
    if (action.payload === FETCH_ARTICLE_DETAILS) {
      return {
        ...state,
        isLoadingData: false
      };
    }
    if (action.payload === FETCH_PEOPLELIST) {
      return {
        ...state,
        isLoadingData: true
      };
    }

Can anyone help to explain why redux overwrite the data? Many Thx.

Edit: changed reducer as suggested, but the same problem.

case SET_ARTICLE_DETAILS:
    return { ...state, data: action.payload };
case SET_PEOPLELIST:
    return { ...state, data: action.payload };
case API_START:
    if (action.payload === FETCH_ARTICLE_DETAILS || action.payload === FETCH_PEOPLELIST) {
      return {
        ...state,
       
      };

Upvotes: 2

Views: 364

Answers (2)

sakshya73
sakshya73

Reputation: 7192

You should have two different variables to store data...in both the cases you are updating the same data variable in your reducer that's why the data is being overwritten.

case SET_ARTICLE_DETAILS:
    return { ...state, articlesData: action.payload };
case SET_PEOPLELIST:
    return { ...state, peoplesData: action.payload };

Upvotes: 1

Linda Paiste
Linda Paiste

Reputation: 42228

A reducer must always return a complete state. It looks like you reducer has properties data and isLoadingData.

This case is good. We copy all of the existing state and then overwrite isLoadingData with a new value.

return {
  ...state,
  isLoadingData: true
};

This case is bad. We return a state which only has the property data. Every other property in the state gets erased.

return {
  data: action.payload
};

You always want to include ...state.

return {
  ...state,
  data: action.payload
};

Upvotes: 0

Related Questions