简体   繁体   中英

Updating value inside nested object of object in React Native

I have state set as follow

const [stories, setStories] = useState([]);

I fetch Data from API in array, and i map the array and set the using setStories as:

setStories(prevState => prevState.concat({user: {name: 'XYZ', profile: 'ABC', stories: [{id: 1, image: 'testing'}];

The above codes are working fine, but i am stuck, when i have to concat the latest story if the id did not matched with fetched data. I have tried below solution but it didnot help:

stories.map(story => {
if(story && story.hasOwnProperty(key)){
//where above key is the user key fetched from the another API, i.e., user key
story?.[key].stories.map(storedStory => 
id(storedStory.id !== fetchedStory.id){
story?.[key].stories.concat({story})}

but the above code did not work, as it only mutate the state and is avoiding re-rendering. Looking for a clean and efficient method to overcome this. THanks

It's hard to tell what you're trying to accomplish without seeing a full example. But I think your main problem is that you're not using the returned value from map , and from the naming it looks like you're appending the wrong element.

It will help to simplify first.

  const newState = stories.map(story => {
    if (story?.hasOwnProperty(key)) {
      const found = story[key].stories.find(s => s.id === fetchedStory.id);

      if (found) {
        return story;
      } else {
        // Let's make a new object with the fetchedStory
        // appended into THIS user's stories
        return {
          ...story,
          [key]: {
            ...story[key],
            stories: [
              ...story[key].stories,
              // This is supposed to be fetchedStory
              // not `story` right??
              fetchedStory,
            ]
          }
        }
      }
    } else {
      return story;
    }
  });

  setStory(newState);

Edit: You're having a hard time expressing your business logic, and the complexity of the data structure is not helping. So keep simplifying, encapsulate the complex syntax into functions then express your business logic plainly. Ie,

const appendStory = (originalObject, userId, storyToAppend) => {
  return {
    ...originalObject,
    [userId]: {
      ...originalObject[userId],
      stories: [
        ...originalObject[userId].stories,
        storyToAppend,
      ]
    }
  }
};

const userExistsInList = (users, user) => {
  return users?.hasOwnProperty(user);
}

const newStoryAlreadyInStories = (stories, newStory) => {
  return stories.find(s => s.id === newStory.id);
}

const newState = stories.map(story => {
  if (userExistsInList(story, key)) {
    
    const found = newStoryAlreadyInStories(story[key].stories, fetchedStory);

    if (found) {
      // User is already in state and the new story is already in the list
      // Add business logic here
    } else {
      // User is already in state and the new story
      // is not in their list
      // Add business logic here
    }
  } else {
    // User is not in the list yet
    // Add business logic here
  }
});

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