React如何根据导入的数据条件渲染不同<div>组件
问题描述
开发个人项目时需要实现标签页切换展示不同内容:
- 仅当导入的数据包含
img字段时,显示className为container的<div> - 仅当数据包含
skill字段时,显示className为skillsList的<div>
目前两个组件在所有标签页都会显示,无法根据数据字段条件控制显示隐藏,现有代码如下:
import React, {useEffect, useState} from "react"; import PortfolioList from "../portfolioList/PortfolioList"; import { skillsPortfolio, webPortfolio, mobilePortfolio, designPortfolio, contentPortfolio} from "../../data"; export default function Portfolio() { const [selected, setSelected] = useState("skills"); const [data, setData] = useState([]); const list = [ { id: "skills", title: "Skills", }, { id: "python", title: "Python", }, { id: "sql", title: "SQL", }, { id: "dataanalysis", title: "Data Analysis", }, ]; useEffect(()=>{ switch(selected){ case "skills": setData(skillsPortfolio); break; case "python": setData(webPortfolio); break; case "sql": setData(mobilePortfolio); break; case "dataanalysis": setData(designPortfolio); break; case "content": setData(contentPortfolio); break; default: setData(skillsPortfolio); } }, [selected]) return( <div className="portfolio" id="portfolio"> <h1>Portfolio</h1> <ul> {list.map((item) => ( <PortfolioList title={item.title} active={selected=== item.id} setSelected={setSelected} id={item.id} /> ))} </ul> <div className="container"> {data.map((d)=> ( <div className="item"> <img src={d.img}/> <h3>{d.title}</h3> </div> ))} </div> <div className="skillsList"> {data.map((d)=> ( <p>{d.skill}</p> ))} </div> </div> ) }
注:映射的数据中,部分条目含img字段,部分含skill字段。Skills标签页的数据无img字段,Python标签页的数据无skill字段。
解决方案
通过条件渲染即可实现需求,核心是判断当前数据中是否存在目标字段,再决定是否渲染对应组件。
修改后的代码
import React, { useEffect, useState } from "react"; import PortfolioList from "../portfolioList/PortfolioList"; import { skillsPortfolio, webPortfolio, mobilePortfolio, designPortfolio, contentPortfolio } from "../../data"; export default function Portfolio() { const [selected, setSelected] = useState("skills"); const [data, setData] = useState([]); const list = [ { id: "skills", title: "Skills" }, { id: "python", title: "Python" }, { id: "sql", title: "SQL" }, { id: "dataanalysis", title: "Data Analysis" }, ]; useEffect(() => { switch(selected) { case "skills": setData(skillsPortfolio); break; case "python": setData(webPortfolio); break; case "sql": setData(mobilePortfolio); break; case "dataanalysis": setData(designPortfolio); break; case "content": setData(contentPortfolio); break; default: setData(skillsPortfolio); } }, [selected]); // 检查数据中是否存在带img字段的条目 const hasImg = data.some(item => "img" in item); // 检查数据中是否存在带skill字段的条目 const hasSkill = data.some(item => "skill" in item); return( <div className="portfolio" id="portfolio"> <h1>Portfolio</h1> <ul> {list.map((item) => ( <PortfolioList title={item.title} active={selected === item.id} setSelected={setSelected} id={item.id} /> ))} </ul> {/* 仅当存在img字段时渲染container */} {hasImg && ( <div className="container"> {data.map((d) => ( <div className="item" key={d.id || d.title}> <img src={d.img}/> <h3>{d.title}</h3> </div> ))} </div> )} {/* 仅当存在skill字段时渲染skillsList */} {hasSkill && ( <div className="skillsList"> {data.map((d) => ( <p key={d.id || d.skill}>{d.skill}</p> ))} </div> )} </div> ); }
关键说明
- 用
Array.some()方法判断数组中是否存在包含目标字段的条目,返回布尔值作为渲染判断依据 - 利用React的**逻辑与(&&)**语法实现条件渲染:左侧表达式为
true时,才会渲染右侧的JSX内容 - 给循环渲染的元素添加
key属性,避免React控制台警告(可使用数据中唯一标识字段,如id,无则用title或skill)
内容的提问来源于stack exchange,提问作者Alexander Wilson
相关产品推荐
相关产品推荐

