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

ReactJS实现点击单个职位仅展开对应详情的问题求助

问题解决:点击单个职位仅展开对应详情

问题根源:你将控制详情展开/收起的状态toggled定义在了父组件App中,所有JobBoardComponent实例共享这一个全局状态,所以点击任意职位卡片时,全局状态变化会触发所有卡片同步展开/收起。

解决方案

把展开状态下移到每个JobBoardComponent内部,让每个卡片独立管理自己的展开状态,不需要父组件传递状态。

1. 修改App.js

删除全局的toggled状态,并移除向JobBoardComponent传递的toggled和setToggled props:

import './App.css';
import React, {useState, useEffect} from 'react'
import jobData from "./assets/data.json"
import JobBoardComponent from './components/JobBoardComponent';
import NavBar from './components/NavBar'
import EmailBar from './components/EmailBar'
import BannerPage from "./components/BannerPage"
import FuncFilter from "./components/FuncFilter"
import LocFilter from "./components/LocFilter"
import ConFilter from './components/ConFilter';

function App() {
  const [jobs, setJobs] = useState([])
  const [filtered, setFiltered] = useState([])
  const [activeCategory, setActiveCategory] = useState(0)
  const [activeLocation, setActiveLocation] = useState(0)
  const [activeContract, setActiveContract] = useState(0)
   
  useEffect(() => {
    setJobs(jobData)
  }, [])

  return (
    <div className="App w-auto">
      <NavBar />
      <BannerPage />
      <EmailBar />
      <FuncFilter 
        jobs={jobs} 
        setFiltered={setFiltered} 
        activeCategory={activeCategory} 
        setActiveCategory={setActiveCategory}
        activeLocation={activeLocation}
        setActiveLocation={setActiveLocation}
        setActiveContract={setActiveContract}
        activeContract={activeContract}
      />
      <LocFilter 
        jobs={jobs} 
        setFiltered={setFiltered} 
        activeLocation={activeLocation}
        setActiveLocation={setActiveLocation}
        setActiveCategory={setActiveCategory}
        activeCategory={activeCategory}
        setActiveContract={setActiveContract}
        activeContract={activeContract}
      />
      <ConFilter 
        jobs={jobs} 
        setFiltered={setFiltered} 
        activeLocation={activeLocation}
        setActiveLocation={setActiveLocation}
        setActiveCategory={setActiveCategory}
        activeCategory={activeCategory}
        setActiveContract={setActiveContract}
        activeContract={activeContract}
      />
      <div>
        { activeCategory == 0 
          ? jobs.map((job) => <JobBoardComponent job={job} key={job.id} />)
          : filtered.map((job) => <JobBoardComponent job={job} key={job.id} />)
        }  
      </div>
    </div>
  );
}

export default App;

2. 修改JobBoardComponent.js

在组件内部添加独立的展开状态,移除不必要的props和useEffect:

import React, {useState} from "react"

function JobBoardComponent({ job }) {
  const [isToggled, setIsToggled] = useState(true);
  const langAndTools = []
  const skill = job.skills
  const tools = job.tools
  
  if (skill && tools) {
    langAndTools.push(...skill)
    langAndTools.push(...tools)
  } 

  const handleClick = event => {
    setIsToggled(!isToggled);
  };

  return ( 
    <div id="jobboard" onClick={handleClick} className={`flex flex-col hover:bg-gray-100  bg-white shadow-md m-4 mb-20 px-6  -mt-10 rounded ${job.featured && 'border-l-4 border-black'}`}>
      <div>
        <img className="-mt-10 mb-4 w-20 h-20" src={job.logo} alt={job.company}></img>
      </div> 
      <div className="text-left  mt-1">
        <h3 className="font-mono font-bold text-blue-600">
          {job.company}
          {job.fresh && (<span className="text-blue-100 bg-blue-500 font-bold m-2 py-1 px-2 rounded-full">New</span>)}
          {job.featured && (<span className="text-white bg-gray-800 font-bold m-2 py-1 px-2 rounded-full">Featured</span>)}
        </h3>
        <h2 className="font-mono font-bold text-xl my-2">{job.position}</h2>
        <p className="font-mono text-gray-700">
          {job.postedAt} · {job.contract} · {job.location}
        </p>
      </div> 
      <div id="jobdesc" className={isToggled ? "hidden font-mono my-10 " : "font-mono my-10"} >
        <h3>Who We Are:</h3>
        <p>{job.whoweare}</p>
        <br></br>
        <h3>Job Description:</h3>
        <p>{job.description}</p>
        <br></br>
        <br></br>
        <a id="applybtn" target="_blank" href={job.joblink} className="font-mono text-white bg-gradient-to-r from-blue-500 via-blue-600 to-blue-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800 font-medium rounded-lg text-sm px-32 py-2 text-center mr-2 content-center"> Apply </a>
        <br></br>
      </div>
      <div className="flex flex-wrap items-center mt-4 mr-4 pt-4 border-t-2 border-gray-300 border-solid">
        {langAndTools ? (
          langAndTools.map((langAndTool) => (
            <span className="text-blue-600 bg-blue-100 font-bold mr-4 mb-4 p-2 rounded">{langAndTool}</span>
          ))
        ) : " "}   
      </div>
    </div> 
  )
}

export default JobBoardComponent

这样修改后,每个职位卡片会独立控制自己的展开/收起状态,点击某一个卡片只会展开对应职位的详情,不会影响其他卡片。

内容的提问来源于stack exchange,提问作者Shaun Smerling

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 07:24:18