如何在React中切换数组内对象的boolean类型visibility属性
问题解决:点击切换对应元素的可见性
你的代码里toggleVisibility函数的逻辑存在问题,主要是修改ids数组时错误覆盖了整个数组,且没有正确返回更新后的状态。以下是修复后的完整代码:
import React, { useState } from "react"; import { v4 as uuidv4 } from 'uuid'; const RestaurantInfo = () => { // 初始化数据时抽离成单独变量,避免组件每次渲染都重新生成uuid const initialData = [ { name: "Haaland Restaurant's", stars: 5, price: "100$", ranking: "top 1 in england", ids: [ { id: uuidv4(), key: uuidv4(), visibility: false }, { id: uuidv4(), key: uuidv4(), visibility: false }, { id: uuidv4(), key: uuidv4(), visibility: false }, ] } ] const [restaurantData, setRestaurantData] = useState(initialData) const toggleVisibility = (id) => { setRestaurantData(prevData => prevData.map(restaurant => { // 遍历当前餐厅的ids数组,仅修改匹配id的对象的visibility属性 const updatedIds = restaurant.ids.map(item => item.id === id ? { ...item, visibility: !item.visibility } : item ) // 返回新的餐厅对象,替换ids为更新后的数组 return { ...restaurant, ids: updatedIds } }) ) } const CardElement = restaurantData.map((data) => ( <div style={{ color: "white" }} key={data.name}> {/* 添加key消除React警告 */} <h1>{data.name}</h1> <div> <div> <h1>Stars</h1> <p id={data.ids[0].id} onClick={() => toggleVisibility(data.ids[0].id)} >{data.ids[0].visibility ? 'hide' : 'show'}</p> {/* 按钮文字随状态切换 */} </div> {data.ids[0].visibility ? <p>{data.stars}</p> : ""} </div> <div> <div> <h1>Price</h1> <p id={data.ids[1].id} onClick={() => toggleVisibility(data.ids[1].id)} >{data.ids[1].visibility ? 'hide' : 'show'}</p> </div> {data.ids[1].visibility ? <p>{data.price}</p> : ""} </div> <div> <div> <h1>Ranking</h1> <p id={data.ids[2].id} onClick={() => toggleVisibility(data.ids[2].id)} >{data.ids[2].visibility ? 'hide' : 'show'}</p> </div> {data.ids[2].visibility ? <p>{data.ranking}</p> : ""} </div> </div> )) return ( <div> {CardElement} </div> ) } export default RestaurantInfo
关键修复说明:
- 修正状态更新逻辑:不再直接覆盖整个
ids数组,而是遍历每个元素只修改匹配id的对象属性,保证数组其他元素不受影响。 - 遵循不可变性原则:每次更新都返回新的对象和数组,不直接修改原状态数据,符合React状态更新规则。
- 细节优化:
- 初始化数据抽离后避免uuid重复生成;
- 给循环组件添加
key属性消除警告; - 按钮文字随可见性状态切换,提升交互体验。
内容的提问来源于stack exchange,提问作者Ayman Loutfi
相关产品推荐
相关产品推荐

