React中多个同类名place-box点击切换全部触发如何解决?
问题修复方案
问题原因
你的猜测不对,该问题和类名没有关联。核心原因是你把isOpen定义为CityResult组件的全局状态,所有循环渲染出来的place-box元素共用这一个布尔值做展示判断,只要状态更新,所有元素都会同步切换展示效果。
修复方案
方案1:仅允许单个地点同时展开(匹配你现有交互预期)
你已经在存储点击的地点id,可以直接复用该状态,无需额外的isOpen变量,修改后代码如下:
import React, { useState } from "react"; import { useQuery } from "@apollo/client"; import { FETCH_CITIES_QUERY } from "../../server/Data/RentQueries"; import PlaceResult from "../Rent/PlaceResult"; const CityResult = (props) => { // 仅存储当前激活展开的地点id,为null则全部关闭 const [activePlaceId, setActivePlaceId] = useState(null); // 补全你代码中缺失的cityName变量提取 const cityName = props.cityName; const { loading, error, data } = useQuery(FETCH_CITIES_QUERY, { variables: { cityName: cityName }, }); const showPlaceInfo = (clickedPlaceId, e) => { e.preventDefault(); // 点击同一个则关闭,点击不同则切换为对应id setActivePlaceId(prevId => prevId === clickedPlaceId ? null : clickedPlaceId); }; return ( <div> {data && data.cities.map((city) => { return ( <div className="city-box" key={city.id}> {city.places.map((place) => { return ( <div className="place-box" key={place.id} onClick={(e) => { e.stopPropagation(); showPlaceInfo(place.id, e); }} > <li className="place-name">{place.name}</li> {/* 判断当前place的id是否等于激活id,决定展示内容 */} {place.id === activePlaceId ? ( <PlaceResult className="place-indiv" placeId={place.id} /> ) : ( <div className="place-info-box"> <li>{place.address}</li> {conditionCheck(city.condition)} <li>{place.phone}</li> </div> )} </div> ); })} </div> ); })} </div> ); }; export default CityResult;
方案2:允许多个地点同时展开
如果需要支持同时打开多个地点卡片,可以用Set存储所有已展开的地点id:
// 状态定义 const [openPlaceIds, setOpenPlaceIds] = useState(new Set()); // 点击逻辑 const togglePlaceInfo = (clickedPlaceId, e) => { e.preventDefault(); setOpenPlaceIds(prev => { const newSet = new Set(prev); if (newSet.has(clickedPlaceId)) { newSet.delete(clickedPlaceId); } else { newSet.add(clickedPlaceId); } return newSet; }) } // 渲染判断 {openPlaceIds.has(place.id) ? ( <PlaceResult className="place-indiv" placeId={place.id} /> ) : ( // 省略默认展示内容 )}
额外提示
你原有代码中useQuery的variables里引用的cityName没有定义,记得从props中提取该变量,否则会触发变量未定义报错。
内容的提问来源于stack exchange,提问作者Ns68
相关产品推荐
相关产品推荐

