React中如何更新含关联属性的state对象?(无Redux)
问题解决:React useState同步currentUser的concerts数组更新
我使用React 16,仅依赖useState Hook,未引入Redux等状态管理库。从Rails后端获取的currentUser对象包含concerts和posts数组,用户可在指定concert下创建或删除post。目前currentUser.posts能即时渲染更新,但currentUser.concerts需手动刷新才会同步后端状态。后端返回的currentUser JSON已完全更新,但前端仅更新了posts字段,导致state未即时同步。因项目时间有限无法引入Redux,需实现以下逻辑:
- 创建post时,若为该concert的首个post,则将其加入
currentUser.concerts - 删除post时,若该concert无剩余post,则将其从
currentUser.concerts移除
创建Post时同步Concerts数组
修改createNewPost.js中的handleSubmit函数,在更新posts的同时检查并添加目标concert:
const handleSubmit = (e) => { e.preventDefault(); fetch('/posts', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', }, body: JSON.stringify({ body: body, for_sale: isSelling, tickets: ticketAmount, concert_id: concert.id, user_id: currentUser.id, }), }).then((response) => { if (response.status >= 200 && response.status <= 299) { response.json().then((createdPost) => { // 检查当前用户的concerts中是否已存在目标concert const concertExists = currentUser.concerts.some(c => c.id === concert.id); // 检查用户是否已有该concert的其他post const hasExistingPosts = currentUser.posts.some(p => p.concert_id === concert.id); let updatedConcerts = [...currentUser.concerts]; // 若concert不存在且是首个post,则添加到concerts数组 if (!concertExists && !hasExistingPosts) { updatedConcerts = [...updatedConcerts, concert]; } // 同步更新currentUser的posts和concerts setCurrentUser({ ...currentUser, posts: [...currentUser.posts, createdPost], concerts: updatedConcerts }); setErrorArray([]); setErrorsExist(false); setSuccess('Your post has been created!'); setSubmitted(true); }); } else { response.json().then((e) => { setErrorsExist(true); setErrorArray(e.errors); }); } }); };
逻辑说明:
- 通过
some方法判断目标concert是否已在currentUser.concerts中 - 同时检查用户是否已有该concert的其他post,确保这是第一个关联post
- 满足条件时将concert添加到concerts数组,最后同步更新整个currentUser state
删除Post时同步Concerts数组
修改DeleteConfirmation.js中的handleDelete函数,删除post后检查对应concert的剩余post数量:
function handleDelete(post) { fetch(`/posts/${post.id}`, { method: 'DELETE', }).then(() => { // 获取删除后的posts数组 const updatedPosts = currentUser.posts.filter( (eachPost) => eachPost.id !== post.id ); // 检查删除后该concert是否还有剩余post const hasRemainingPosts = updatedPosts.some(p => p.concert_id === post.concert_id); let updatedConcerts = [...currentUser.concerts]; // 若无剩余post,则从concerts数组中移除该concert if (!hasRemainingPosts) { updatedConcerts = updatedConcerts.filter(c => c.id !== post.concert_id); } // 同步更新currentUser的posts和concerts setCurrentUser({ ...currentUser, posts: updatedPosts, concerts: updatedConcerts }); }); }
逻辑说明:
- 先过滤得到删除后的posts数组
- 用
some方法检查更新后的posts中是否还有同一concert的其他post - 若无剩余post,则从concerts数组中过滤掉该concert,最后同步更新currentUser state
内容的提问来源于stack exchange,提问作者Maj Aliju
相关产品推荐
相关产品推荐

