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

react-bootstrap渲染图片出现重复输出(12张而非4张)bug如何修复?

问题原因
  • 同层级兄弟组件key重复:你上下两行的4个Col组件全部使用了相同的设施Id作为key值,React要求同层级兄弟元素的key必须唯一,否则diff算法无法正确识别需要卸载的旧节点,导致历史渲染的图片节点不断累积,每切换一次按钮就多渲染4张,切换3次就会出现12张的问题。
  • 按钮取值逻辑错误:React-Bootstrap的Button是封装组件,点击时e.target可能指向按钮内部的文本节点而非按钮本身,会出现拿不到value的情况,导致匹配不到正确的设施数据。
  • 额外说明:你第一个设施De'Spa的四个图片路径填的都是同一个,修复后会显示4张相同的图,如需不同请自行修改路径。
修复方案
  1. 给每个Col设置唯一key,拼接图片位置标识保证同层级key不重复
  2. 按钮点击事件用e.currentTarget.value替代e.target.value,保证拿到正确绑定的按钮值
  3. 用Array.find替代filter查找当前设施,性能更高,同时添加兜底判断避免匹配不到数据时报错
  4. 给img标签补充alt属性,符合前端规范
修复后完整代码
import { useState, useEffect } from 'react';
import { Container, Row, Col, Button } from 'react-bootstrap';

const facsInfo = [
    {
        Id: "1",
        Title: "De'Spa",
        Description: "",
        upperleftimg:"./Images/DeSpa1.jpg",
        upperrightimg:"./Images/DeSpa1.jpg",
        bottomleftimg:"./Images/DeSpa1.jpg",
        bottomrightimg:"./Images/DeSpa1.jpg",
    },
    {
        Id: "2",
        Title: "De'Resto",
        Description:" ",
        upperleftimg:"./Images/DeResto1.jpg",
        upperrightimg:"./Images/DeResto2.jpg",
        bottomleftimg:"./Images/DeResto3.jpg",
        bottomrightimg:"./Images/DeResto4.jpg",
    },
    {
        Id: "3",
        Title: "Meeting Room",
        Description: "",
        Opentime:"Opening hours: 10.00 am – 8.00 pm",
        upperleftimg:"./Images/Room1.jpg",
        upperrightimg:"./Images/Room2.jpg",
        bottomleftimg:"./Images/Room3.jpg",
        bottomrightimg:"./Images/Room4.jpg",
    },
]

const Facilities = () => {
    const [currentId, setCurrentId] = useState("1");

    useEffect(() => {
      console.log(currentId);
    }, [currentId]);
  
    const showSelectedFact = () => {
      const fac = facsInfo.find((x) => x.Id === currentId);
      if (!fac) return null;
      const { Title, Description, Opentime, Id } = fac;
      return (
        <div key={Id}>
          <h1 className="fontSB">{Title}</h1>
          <p>{Description}</p><br></br>
          <p><b>{Opentime}</b></p>
        </div>
      );
    };

    const showSelectedUpperImage = () => {
        const fac = facsInfo.find((x) => x.Id === currentId);
        if (!fac) return null;
        const { upperleftimg, upperrightimg, Id } = fac;
        return (
            <>
                <Col key={`${Id}-upper-left`} className="facsImage text-center" md={12} lg={6}>
                    <img className="img-fluid" src={upperleftimg} alt={upperleftimg}></img>
                </Col>

                <Col key={`${Id}-upper-right`} className="facsImage text-center" md={12} lg={6}>
                    <img className="img-fluid" src={upperrightimg} alt={upperrightimg}></img>
                </Col>
            </>
        );
      };


      const showSelectedBottomImage = () => {
        const fac = facsInfo.find((x) => x.Id === currentId);
        if (!fac) return null;
        const { bottomleftimg, bottomrightimg, Id } = fac;
        return (
            <>
                <Col key={`${Id}-bottom-left`} className="facsImage text-center" sm={12} md={12} lg={6}>
                    <img className="img-fluid" src={bottomleftimg} alt={bottomleftimg}></img>
                </Col>

                <Col key={`${Id}-bottom-right`} className="facsImage text-center" sm={12} md={12} lg={6}>
                    <img className="img-fluid" src={bottomrightimg} alt={bottomrightimg}></img>
                </Col>
            </>
        );
      };  

    return (
        <>
            <Container fluid>
                <Row className="facsbuttwrapper text-center">
                    <Col sm={4} lg={4}>
                        <Button
                        value="1"
                        variant="custom"
                        onClick={(e) => setCurrentId(e.currentTarget.value)}
                        >
                        De'Spa
                        </Button>
                    </Col>

                    <Col sm={4} lg={4}>
                        <Button
                        value="2"
                        variant="custom"
                        onClick={(e) => setCurrentId(e.currentTarget.value)}
                        >
                        De'Resto
                        </Button>
                    </Col>

                    <Col sm={4} lg={4}>
                        <Button
                        value="3"
                        variant="custom"
                        onClick={(e) => setCurrentId(e.currentTarget.value)}
                        >
                        Meeting Room
                        </Button>
                    </Col>
                </Row>
            </Container>

            <Container fluid>
                <Row className="facsDetail fontReg">
                    <Col className="text-center" md={12} lg={12}>
                        {showSelectedFact()}
                    </Col>
                </Row>
            </Container>

            <Container fluid>
                <Row>
                    {showSelectedUpperImage()}
                </Row>
            </Container>

            <Container fluid>
                <Row>
                    {showSelectedBottomImage()}
                </Row>
            </Container>
        </>
    )
}

export default Facilities

内容的提问来源于stack exchange,提问作者Kim San

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:48:00