React Hooks动态映射子组件评论独立展开状态异常求解
问题根因
你当前使用单一布尔类型的showComment状态控制所有帖子的评论显隐,所有帖子组件共享同一个全局状态,因此触发切换时所有评论区会同步开关。
同时原代码还存在几个语法/逻辑问题需要修正:
useEffect直接传入async函数不符合React规范,会导致警告,需要在钩子内部定义异步函数再执行useEffect中使用的page变量未定义- 子组件
Child的map遍历没有返回值,且渲染的组件名和实际定义的RenderText不符
方案1:父组件存储激活状态(适合需要父组件感知当前打开评论的场景)
修改父组件状态为存储当前打开评论区的帖子ID,点击时匹配ID判断是否显隐:
父组件代码
import React, { useState, useEffect } from "react"; import { getLatestFeed } from "../services/axios"; import Child from "./Child"; const Parent= () => { const [latestFeed, setLatestFeed] = useState("loading"); // 存储当前打开评论的帖子ID,null代表所有评论区关闭 const [openCommentPostId, setOpenCommentPostId] = useState(null); useEffect(() => { // 内部定义异步函数避免useEffect警告 const fetchFeed = async () => { // 补充你的page参数定义 const page = 1; const newLatestFeed = await getLatestFeed(page); setLatestFeed(newLatestFeed); } fetchFeed(); }, []); // 接收点击的帖子ID做判断 const handleComment = (postId) => { setOpenCommentPostId(prev => prev === postId ? null : postId); }; return ( <div className="dashboardWrapper"> <Child posts={latestFeed} openCommentPostId={openCommentPostId} handleComment={handleComment} /> </div> ); }; export default Parent;
子组件代码
import React from "react"; const RenderText = ({ post, openCommentPostId, handleComment }) => { return ( <div className="postWrapper"> <p>{post.title}</p> <p>{post.body}</p> {/* 匹配ID判断当前帖子评论是否显示 */} <Comments id={post._id} showComment={openCommentPostId === post._id} handleComment={() => handleComment(post._id)} /> </div> ); }; const Child = ({ posts, openCommentPostId, handleComment }) => { // 修正map返回值和组件名 return ( <div> {posts.map((post) => ( <RenderText key={post._id} post={post} openCommentPostId={openCommentPostId} handleComment={handleComment} /> ))} </div> ); }; export default Child;
方案2:状态下沉到帖子组件(更轻量化的实现)
如果父组件不需要感知哪个帖子的评论处于打开状态,直接把开关状态放到每个RenderText组件内部即可,每个组件独立维护自己的状态,互不干扰:
修改后的RenderText组件
import React, { useState } from "react"; const RenderText = ({ post }) => { // 每个帖子自己维护评论开关状态 const [showComment, setShowComment] = useState(false); return ( <div className="postWrapper"> <p>{post.title}</p> <p>{post.body}</p> <Comments id={post._id} showComment={showComment} handleComment={() => setShowComment(prev => !prev)} /> </div> ); };
此时父组件不需要再存储showComment相关的状态和处理函数,直接传递posts给子组件即可。
内容的提问来源于stack exchange,提问作者ThirdGhostHand
相关产品推荐
相关产品推荐

