如何实现切换开关控制数组对象的描述显示/隐藏?
问题修复方案
核心问题分析
- 状态设计错误:用数组存储所有描述,未贴合全局开关的控制逻辑
- 渲染逻辑错误:直接渲染整个描述数组,而非当前结果的专属描述
- 开关未设置默认勾选状态,切换逻辑不符合显示/隐藏的双向需求
修复步骤
- 修改状态定义:将存储描述数组的状态改为布尔值
showDescriptions,默认设为true(满足默认勾选显示的需求) - 修正渲染逻辑:列表项中根据
showDescriptions状态,决定是否渲染当前result的专属描述 - 修复开关行为:给input添加
checked属性绑定状态,切换函数改为反转布尔值 - 规范列表渲染:给每个列表项添加唯一key,符合React渲染规范
- 修正SVG引用:使用定义好的
upvoteSVG和downvoteSVG变量替换硬编码路径
修复后的完整代码
// imports const results = [...] const upvoteSVG = '...'; const downvoteSVG = '...'; export default function SearchResults() { const [page, setPage] = useState(0); // 布尔值控制全局描述显示状态,默认开启 const [showDescriptions, setShowDescriptions] = useState(true); const List = () => { return ( <> {results.slice(page * 10, page * 10 + 10).map((result) => ( <div key={result.id || result.name} className="bg-gray-800 shadow-lg shadow-red-500 m-5"> <div className="flex flex-row gap-4 p-5"> <div className="flex flex-col w-1/2"> <div className="flex flex-row gap-4"> <p className="text-lg font-bold">{result.name}</p> <p className="text-blue-500"><Link href={result.url}>Website</Link></p> </div> <p>{result.categories.slice(0, 3).join(", ")}</p> </div> <div className="flex flex-row flex-wrap w-1/2"> {/* 根据状态显示当前结果的专属描述 */} {showDescriptions && <p>{result.description}</p>} </div> </div> <div className="flex flex-row bottom-0 gap-4 bg-gray-900 justify-items-end justify-end pr-2"> <p>{result.upvotes} <button className="rounded-full bg-red-500 w-fit h-fit p-2 m-2"> <Image src={upvoteSVG} alt="upvote" width={20} height={20}/> </button> </p> <p>{result.downvotes} <button className="rounded-full bg-red-500 w-fit h-fit p-2 m-2"> <Image src={downvoteSVG} alt="downvote" width={20} height={20}/> </button> </p> </div> </div> ))} </> ) } const prevPage = () => { if (page > 0) setPage(page - 1); } const nextPage = () => { if ((page + 1) * 10 < results.length) setPage(page + 1); } // 切换描述显示状态 const toggleDescriptions = () => { setShowDescriptions(prev => !prev); } const PaginationNumbers = () => { const totalPages = Math.ceil(results.length / 10); return Array.from({length: totalPages}, (_, i) => ( <button key={i} onClick={() => setPage(i)} className={`m-1 p-2 rounded-lg ${page === i ? 'bg-white text-black' : 'bg-gray-800 text-white'}`} > {i + 1} </button> )); } const NOP = () => { return null; } return ( <div className="flex flex-col justify-center items-center"> <div> <Search/> </div> <div className="flex flex-row justify-center items-center"> <div className="w-1/2"> <List/> </div> <div className="w-1/2 m-2 p-2 flex flex-col justify-center items-center bg-gray-800"> <label className="inline-flex items-center cursor-pointer"> {/* 绑定状态,默认勾选 */} <input type="checkbox" value="" className="sr-only peer" id="toggle" onChange={toggleDescriptions} checked={showDescriptions} /> <span className="ms-3 text-sm font-medium text-gray-900 dark:text-gray-300 m-2">Show Description</span> <div className="relative w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-red-500 dark:peer-focus:ring-red-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-red-600" ></div> </label> </div> </div> <div className="flex flex-row justify-center items-center flex-wrap w-1/2"> <button onClick={prevPage} className="bg-gray-800 text-white m-2 p-2 hover:bg-white hover:text-black rounded-lg">Prev</button> <PaginationNumbers/> <button onClick={nextPage} className="bg-gray-800 text-white m-2 p-2 hover:bg-white hover:text-black rounded-lg">Next</button> </div> </div> ) }
关键修复说明
- 状态简化:用布尔值替代数组,精准控制全局显示/隐藏,减少冗余状态
- 渲染精准:每个结果仅渲染自身的描述,解决原代码显示所有描述的问题
- 开关双向可控:绑定
checked属性确保默认勾选,切换函数实现显示与隐藏的双向切换 - 符合React规范:添加列表项key,避免渲染警告
内容的提问来源于stack exchange,提问作者Burner
相关产品推荐
相关产品推荐

