You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 17:27:52