首页 > 解决方案 > 在 React Native 中更新对象的嵌套对象内的值

问题描述

我的状态设置如下

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

我从数组中的 API 获取数据,然后映射数组并将使用 setStories 设置为:

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

上面的代码工作正常,但我被卡住了,如果 id 与获取的数据不匹配,我必须连接最新的故事。我尝试了以下解决方案,但没有帮助:

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})}

但是上面的代码不起作用,因为它只会改变状态并且避免重新渲染。寻找一种干净有效的方法来克服这个问题。谢谢

标签: javascriptarraysreact-nativeobjectecmascript-6

解决方案


如果没有完整的示例,很难说出您要完成的工作。但我认为您的主要问题是您没有使用 from 的返回值map,并且从命名看来您添加了错误的元素。

这将有助于首先简化。

  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);

编辑:您很难表达您的业务逻辑,并且数据结构的复杂性无济于事。所以继续简化,将复杂的语法封装成函数,然后简单地表达你的业务逻辑。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
  }
});

推荐阅读