React开发portfolio项目页点击单个read more所有项目均展开如何修复?
问题原因
- 当前你定义的
readMore是父组件全局的布尔状态,所有项目卡片共用这一个状态值,只要状态发生变更,所有卡片的展开/收起逻辑都会同步触发,这是导致所有项目同时展开/收起的核心原因。 - 点击触发的
functionToggle仅对全局状态做取反操作,没有区分当前操作对应的具体项目。
可行修复方案
这里提供两种常用实现方式,可根据需求选择:
方案1:父组件存储展开项目ID(仅支持同时展开1个项目)
步骤1:修改状态定义
将原来的布尔状态替换为存储当前展开项目ID的状态:
// 原代码:const [readMore, setReadMore] = useState(false) const [expandedProjectId, setExpandedProjectId] = useState(null)
步骤2:修改切换函数,接收项目ID作为参数
const functionToggle = (projectId) => { // 点击已展开的项目则收起,否则切换为当前点击项目展开 setExpandedProjectId(prevId => prevId === projectId ? null : projectId) }
步骤3:修改渲染逻辑,按ID匹配状态
<PortfolioContainer> <SingleProjectContainer> {projectData.map((singleProject)=>{ const {title, description, id} = singleProject; const lessDescription = description.slice(0,100) + "...."; const isExpanded = expandedProjectId === id; return ( <div className="cardStyled" key={id}> <ProjectName>{title}</ProjectName> {isExpanded ? <ProjectDescription>{description}</ProjectDescription> : <ProjectDescription>{lessDescription}</ProjectDescription>} <span className="test" onClick={() => functionToggle(id)}>{isExpanded ? "read less" : "read more"}</span> </div> ); })} </SingleProjectContainer> </PortfolioContainer>
方案2:拆分单项目为独立组件(支持同时展开多个项目,推荐)
将单个项目卡片拆分为独立组件,每个组件内部维护自己的展开状态,逻辑解耦更易维护。
步骤1:新建SingleProjectCard.jsx组件
import { useState } from 'react'; // 引入你的样式组件,路径根据实际情况调整 import { ProjectName, ProjectDescription } from './style'; const SingleProjectCard = ({ project }) => { // 组件内部私有状态,仅控制当前卡片的展开/收起 const [readMore, setReadMore] = useState(false); const { title, description, id } = project; const lessDescription = description.slice(0, 100) + "...."; const functionToggle = () => { setReadMore(!readMore); }; return ( <div className="cardStyled" key={id}> <ProjectName>{title}</ProjectName> {readMore ? <ProjectDescription>{description}</ProjectDescription> : <ProjectDescription>{lessDescription}</ProjectDescription>} <span className="test" onClick={functionToggle}>{readMore ? "read less" : "read more"}</span> </div> ); }; export default SingleProjectCard;
步骤2:父组件直接调用子组件
import SingleProjectCard from './SingleProjectCard'; // 父组件渲染逻辑简化为: <PortfolioContainer> <SingleProjectContainer> {projectData.map((singleProject)=> ( <SingleProjectCard key={singleProject.id} project={singleProject} /> ))} </SingleProjectContainer> </PortfolioContainer>
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

