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

React社交信息流组件状态更新异常:新增帖子覆盖原有内容

问题:React社交信息流新增帖子内容被覆盖

向信息流添加新帖子时,第一个新增帖子显示正常,但后续帖子未显示自身内容,而是被第一个新增帖子的值覆盖。控制台显示posts数组存储的值正确,但页面无法正常渲染。

相关代码

Feed组件

import PostBox from '../PostBox/PostBox';
import Posts from '../Post/Posts';
import PostsResult from '../PostsResult/PostsResult';
import PostList from '../Post/PostsList';

const Feed = () => {
    const [posts, setPosts] = useState(PostList);
    const [isUpdated, setIsUpdated] = useState(false);

    const addPost = (postContent) => {
        const newPost = {
            username: "username", 
            timestamp: "Just now",
            content: postContent,
            likes: 0,
            comments: [],
            image: ""
        };
        
        setIsUpdated(true);
        setPosts([newPost, ...posts,]);  
    }

    return (
        <div>
            <PostBox addPost={addPost} />
            {isUpdated ? <PostsResult posts={posts} /> : <Posts posts={posts} />}
        </div>
    );
};

export default Feed;

PostsResult组件

import React from 'react';
import CreatePost from '../Post/CreatePost';

function PostsResult({ posts }) {
    const renderedPosts = posts.map((post) => (
        <CreatePost {...post} />
    ));

    console.log("Posts in PostsResult", posts);
    
    return (
        <div>
            {renderedPosts}
        </div>
    );
}

export default PostsResult;

CreatePost组件

import React, { useState } from 'react';
import './Post.css';

const CreatePost = ({ id, username, timestamp, originalContent, likes, comments, image }) => {
  const [isLiked, setIsLiked] = useState(false);
  const [isRemoved, setIsRemoved] = useState(false);
  const [isEditing, setIsEditing] = useState(false);
  const [editableContent, setEditableContent] = useState(originalContent);

  const Remove = () => {
    setIsRemoved(true);
  };

  const handleLike = () => {
    setIsLiked(!isLiked);
  };

  const handleEdit = () => {
    setIsEditing(true);
  };

  const handleSave = () => {
    setIsEditing(false);
    // Here you would typically update the post content in your backend
    // For now, we're just updating the local state
  };

  const handleChange = (event) => {
    setEditableContent(event.target.value);
  };

  if (isRemoved) {
    return null;
  }


  return (
    isRemoved ? null :
      <div className="post">
        <div className="post-header">
          <div className="post-header-info">
            <p className="username">{username}</p>
            <p className="timestamp">{timestamp}</p>
          </div>
          <div className="post-header-actions">
            {isEditing ? (
              <button onClick={handleSave}>Save</button>
            ) : (
              <i className="bi bi-pencil-square Edit" onClick={handleEdit}></i>
            )}
            <button className="x-button" onClick={Remove}><i className="bi bi-x-lg"></i></button>
          </div>
        </div>

        <div className="post-content">
          {isEditing ? (
            <textarea value={editableContent} onChange={handleChange} className="edit-textarea" />
          ) : (
            <p>{editableContent}</p>
          )}
          {image && <img src={image} alt="Post Image" className="post-image" />}
        </div>

        <div className="buttons">
          <button className="like-button" onClick={handleLike}>
            <i className="bi bi-hand-thumbs-up"></i>
            &nbsp; Likes: {isLiked ? likes + 1 : likes}
          </button>

          <button className="comment-button">
            <i className="bi bi-chat"></i>
            &nbsp; Comments: {comments.length}
          </button>

          <button className="share-button">
            <i className="bi bi-send"></i>
            &nbsp; Share
          </button>
        </div>
      </div>
  );
};

export default CreatePost;

问题原因

  1. 缺少唯一key属性:React渲染列表时需要每个元素有唯一key来区分组件实例。你的PostsResult中渲染CreatePost时没有添加key,导致React复用旧组件实例,状态(比如editableContent)没有重置,显示错误内容。
  2. props字段不匹配:CreatePost接收的是originalContent,但新增帖子时传入的是content,导致初始editableContent未正确赋值,复用组件时显示错误内容。
  3. 新增帖子无唯一标识:新创建的帖子没有id,无法提供可靠的key值。

解决方法

1. 为列表项添加唯一key

修改PostsResult组件的map逻辑,使用帖子的id作为key:

function PostsResult({ posts }) {
    const renderedPosts = posts.map((post) => (
        <CreatePost key={post.id} {...post} />
    ));

    console.log("Posts in PostsResult", posts);
    
    return (
        <div>
            {renderedPosts}
        </div>
    );
}

2. 统一props字段名

两种方案选其一:

  • 方案A:修改CreatePost接收的props字段
    将originalContent改为content,匹配新增帖子的字段:
const CreatePost = ({ id, username, timestamp, content, likes, comments, image }) => {
  const [editableContent, setEditableContent] = useState(content);
  // 其余代码中所有`originalContent`替换为`content`
};
  • 方案B:修改新增帖子的字段名
    将content改为originalContent,匹配CreatePost的props:
const newPost = {
    id: Date.now(), // 新增唯一id
    username: "username", 
    timestamp: "Just now",
    originalContent: postContent,
    likes: 0,
    comments: [],
    image: ""
};

3. 为新增帖子生成唯一id

在Feed组件的addPost方法中,给新帖子添加唯一标识(这里用Date.now(),也可以使用uuid库生成更可靠的id):

const addPost = (postContent) => {
    const newPost = {
        id: Date.now(),
        username: "username", 
        timestamp: "Just now",
        content: postContent, // 或originalContent,对应上面的方案
        likes: 0,
        comments: [],
        image: ""
    };
    
    setIsUpdated(true);
    setPosts([newPost, ...posts]);  
}

4. 可选:简化组件切换逻辑

当前isUpdated状态用来切换Posts和PostsResult,如果这两个组件功能重复,可以直接移除isUpdated状态,始终渲染PostsResult:

const Feed = () => {
    const [posts, setPosts] = useState(PostList);

    const addPost = (postContent) => {
        const newPost = {
            id: Date.now(),
            username: "username", 
            timestamp: "Just now",
            content: postContent,
            likes: 0,
            comments: [],
            image: ""
        };
        
        setPosts([newPost, ...posts]);  
    }

    return (
        <div>
            <PostBox addPost={addPost} />
            <PostsResult posts={posts} />
        </div>
    );
};

内容的提问来源于stack exchange,提问作者Alfa Hores

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 19:23:15