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
相关产品推荐
相关产品推荐

