You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需Redux/Immer,如何更新React嵌套state中的多属性?

解决方案

首先你代码里更新currentUser的写法有语法错误,先修正这一步:

// 错误写法
// setCurrentUser(...currentUser, currentUser.posts: updatedPosts)

// 正确写法:用对象展开运算符替换posts属性
const updatedCurrentUser = { ...currentUser, posts: updatedPosts };
setCurrentUser(updatedCurrentUser);

接下来把更新后的currentUser同步到users数组里,直接通过map遍历匹配用户ID替换即可:

setUsers(prevUsers => prevUsers.map(user => 
  user.id === updatedCurrentUser.id ? updatedCurrentUser : user
));

按照考核要求,你还需要同步更新concerts数组的对应内容——找到新post所属的演唱会,把post添加到它的posts列表,同时同步该演唱会下的用户信息:

setConcerts(prevConcerts => prevConcerts.map(concert => {
  if (concert.id === createdPost.concert_id) {
    // 避免重复添加post
    const postExists = concert.posts.some(post => post.id === createdPost.id);
    return {
      ...concert,
      posts: postExists ? concert.posts : [...concert.posts, createdPost],
      // 同步演唱会下的当前用户信息
      users: concert.users.map(u => 
        u.id === updatedCurrentUser.id ? { ...updatedCurrentUser } : u
      )
    };
  }
  return concert;
}));

整合后的完整代码片段

if (response.status >= 200 && response.status <= 299) {
  response.json().then((createdPost) => {
    console.log('createdPost: ', createdPost);
    
    // 注意:如果是**新增post**用下面的写法,比map更高效;如果是更新已有post,再用你原来的map逻辑
    const updatedPosts = [...currentUser.posts, createdPost];
    
    console.log('updatedPosts: ', updatedPosts);
    const updatedCurrentUser = { ...currentUser, posts: updatedPosts };
    
    // 更新当前用户
    setCurrentUser(updatedCurrentUser);
    // 更新users数组
    setUsers(prevUsers => prevUsers.map(user => 
      user.id === updatedCurrentUser.id ? updatedCurrentUser : user
    ));
    // 更新concerts数组
    setConcerts(prevConcerts => prevConcerts.map(concert => {
      if (concert.id === createdPost.concert_id) {
        const postExists = concert.posts.some(p => p.id === createdPost.id);
        return {
          ...concert,
          posts: postExists ? concert.posts : [...concert.posts, createdPost],
          users: concert.users.map(u => 
            u.id === updatedCurrentUser.id ? { ...updatedCurrentUser } : u
          )
        };
      }
      return concert;
    }));
  });
  setError([]);
  setSuccess('Your post has been created!');
  setSubmitted(true);
} else {
  // 错误处理逻辑
}

关键注意点

  • 用函数式更新(比如setUsers(prevUsers => ...))获取最新的state值,避免异步更新导致的旧值问题
  • 新增post时直接展开原数组加新项,比遍历替换更高效;只有更新已有post时才需要用map匹配替换
  • 同步concerts时检查post是否已存在,防止重复添加

内容的提问来源于stack exchange,提问作者Maj Aliju

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 19:10:33