提问者:小点点

React Js:如何在DOM中只显示一次组件?


我是新鲜的新反应,并试图建立一个简单的博客项目。

这个博客将显示一个帖子列表,访问者可以点击评论在帖子下面显示。

这里是我的问题,我想要一个特定的行为女巫是我想要用户能够显示一次只有一个评论框/窗口。

如果你点击了另一个评论链接,我想强迫其他的关闭。

我不知道该怎么做...

下面是一些代码来表示我的实际应用程序:CondeSandBox

很抱歉我的英语不好...


共2个答案

匿名用户

无论如何,您都需要在所有注释之间共享状态,以便执行此操作。这将使您至少返回两层,即displayposts。您可以向下传递statesetstate,也可以使用上下文。

这是您修改的沙箱,通过上下文使用共享状态。以下是这方面的简单内容:

首先,在app.js(或DisplayPosts,并不重要)中,创建上下文并用提供程序包装返回:

export const CommentContext = createContext(-1);
export default function App() {
  const [post, setPost] = useState(-1);
  return (
    <CommentContext.Provider value={{ post, setPost }}>
      <div className="App">...</div>
    </CommentContext.Provider>
  );
}

接下来在posts.js中,您只需要使用Context而不是usEstate:

const Post = ({ props }) => {
  const { post, setPost } = useContext(CommentContext);
  const { id, title, comments } = props;
  const handleClick = (e) => { // ...
    setPost((pid) => (pid === id ? -1 : id));
  };

  return (<>...
      {post === id ? <DisplayComments postId={id} /> : null}
    </>);
};

这样,您就有了一个显示评论的状态,它是应该显示评论的帖子的id。如果不显示任何注释,它会被设置为-1(我假设您没有-1ID...您可以在那个地方使用null或其他任何东西。

*编辑:在沙箱中,我对代码进行了一些重构,以便更好地分离组件。我把所有的上下文/提供程序都放在了DisplayComments中,一个非常基本的包装器提供程序组件导入到了App中。这样,它将评论逻辑和状态排除在主应用程序功能之外。

这里的示例代码保持不变,因为它使代码更短、更简单,便于说明。

匿名用户

您只需要在displayposts组件上定义一个新的状态值。

displayPosts.js

const DisplayPosts = () => {
  const [openedComments, setOpenedComments] = useState();

  const handleCommentOpen = (id) => {
    if (openedComments === id)
        setOpenedComments(null)
    else 
        setOpenedComments(id)
  }

  return data.map((post) => (
          <Post openedComments onCommentsOpen={() => handleCommentOpen(post.id)} key={post.id} props={post} />
        ))
}

post.js

const Post = ({ openedComments, onCommentsOpen }) => {
  return (
     <a href="/#" onClick={onCommentsOpen}>
        Comments: {comments}
     </a>
     {openedComments === id && <DisplayComments postId={id} />}
  )
}