无需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
相关产品推荐
相关产品推荐

