React实现支持多语言、可过滤的动态工作经历列表渲染
实现步骤
1. 重构通用JobCard组件
去掉原有组件里写死的en语言耦合,组件只接收单条工作数据作为参数,负责单卡片渲染,不关心当前语言是什么,同时补上原组件遗漏的position字段渲染:
export function JobCard({ jobData }) { const skillItems = jobData.skills.map((skill, idx) => <li key={idx}>{skill}</li>); return ( <div className="job-card"> <div className="job-card-title"> <h3>{jobData.name}</h3> <p className="job-position">{jobData.position}</p> <p className="job-date">{jobData.date}</p> </div> <div className="job-card-content"> <ul>{skillItems}</ul> </div> </div> ); }
2. 父组件实现状态管理与动态渲染
在简历页面父组件中维护当前语言、过滤关键词两个核心状态,完全保留原有languageOption数据源格式不做修改,通过记忆化计算得到当前需要展示的工作列表,切换语言、修改过滤条件时列表自动更新:
import { useState, useMemo } from 'react'; import { JobCard } from './JobCard'; // 原有双语言数据源保持原样,后续新增语言直接在对象中追加对应数组即可 const languageOption = { en: [ { name: "Company X", position: "Programmer", date: "Aug 2022 - Present", skills: ["eating", "sleeping", "programming"] }, { name: "Company Y", position: "IT Manager", date: "Jan 2022 - Jul 2022", skills: [ "playing games", 'saying "Have you tried turning it off and on again?"' ] }, { name: "Company Z", position: "Marketing Manager", date: "Jan 2021 - Dec 2021", skills: [ "leading a team", "creating content", "eating free samples", "having fun" ] } ], pl: [ { name: "Firma X", position: "Programista", date: "Sie 2022 - Obecna", skills: ["jedzenie", "spanie", "programowanie"] }, { name: "Firma Y", position: "Kierownik IT", date: "Sty 2022 - Lip 2022", skills: [ "granie w gry", 'mówienie "Czy spróbowałeś wyłączyć i włączyć ponownie?"' ] }, { name: "Firma Z", position: "Manager Marketingu", date: "Sty 2021 - Gru 2021", skills: [ "prowadzenie zespołu", "tworzenie treści", "jedzenie darmowych sampli", "bawienie się dobrze" ] } ] }; export default function WorkExperienceSection() { // 默认语言设为英文 const [currentLang, setCurrentLang] = useState('en'); // 过滤关键词状态 const [filterKeyword, setFilterKeyword] = useState(''); // 计算当前需要展示的工作列表,依赖变化时自动重算 const displayJobs = useMemo(() => { const sourceList = languageOption[currentLang] ?? []; const keyword = filterKeyword.trim().toLowerCase(); // 无关键词直接返回全量数据 if (!keyword) return sourceList; // 过滤规则:匹配公司名、职位、技能包含关键词的条目,可按需扩展 return sourceList.filter(job => { const baseMatch = job.name.toLowerCase().includes(keyword) || job.position.toLowerCase().includes(keyword); const skillMatch = job.skills.some(skill => skill.toLowerCase().includes(keyword)); return baseMatch || skillMatch; }); }, [currentLang, filterKeyword]); return ( <div className="work-experience-wrapper"> {/* 语言切换按钮组 */} <div className="lang-switch-group"> <button className={currentLang === 'en' ? 'active' : ''} onClick={() => setCurrentLang('en')} > English </button> <button className={currentLang === 'pl' ? 'active' : ''} onClick={() => setCurrentLang('pl')} > Polski </button> </div> {/* 过滤输入框 */} <div className="filter-bar"> <input type="text" placeholder="输入关键词过滤工作经历" value={filterKeyword} onChange={(e) => setFilterKeyword(e.target.value)} /> </div> {/* 工作卡片列表 */} <div className="job-card-list"> {displayJobs.map((job, idx) => ( <JobCard key={`${currentLang}-${idx}`} jobData={job} /> ))} </div> </div> ); }
核心逻辑说明
- 完全保留原有JS对象格式的数据源,后续新增语言、修改工作经历数据不需要调整组件渲染逻辑
- 卡片组件和语言逻辑完全解耦,只负责单条数据渲染,可复用性更强
- 列表key拼接了当前语言前缀,避免切换语言时React错误复用组件导致的渲染异常
- 所有动态更新逻辑由React状态驱动,切换语言、修改过滤条件后卡片列表自动刷新,不需要手动操作DOM
- 后续如果需要加排序、时间范围筛选等功能,只需要修改
displayJobs的计算逻辑即可,不需要改动数据源和卡片组件
内容的提问来源于stack exchange,提问作者NLIArthour
相关产品推荐
相关产品推荐

