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

如何实现切换开关控制数组对象的描述显示/隐藏?

问题修复方案

核心问题分析

  • 状态设计错误:用数组存储所有描述,未贴合全局开关的控制逻辑
  • 渲染逻辑错误:直接渲染整个描述数组,而非当前结果的专属描述
  • 开关未设置默认勾选状态,切换逻辑不符合显示/隐藏的双向需求

修复步骤

  1. 修改状态定义:将存储描述数组的状态改为布尔值showDescriptions,默认设为true(满足默认勾选显示的需求)
  2. 修正渲染逻辑:列表项中根据showDescriptions状态,决定是否渲染当前result的专属描述
  3. 修复开关行为:给input添加checked属性绑定状态,切换函数改为反转布尔值
  4. 规范列表渲染:给每个列表项添加唯一key,符合React渲染规范
  5. 修正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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 10:05:22