使用反应挂钩更改图像和描述 onClick 的最佳方法

Best way to change image and description onClick with react hooks

我有一个服务列表,列表旁边显示的是一张图片和一段描述,基本上当我点击列表项时我想让图片变成相应的image/description。现在我的图像在 onClick 上发生了变化,这很好,但我不确定同时更改描述的最佳方式。我应该为每个服务创建一个对象,其中包括图像 src 然后还有文本吗?我将如何使用 React Hooks 来做到这一点? onClick/object 会是什么样子?

import React, { useState, useEffect } from "react"
import styles from "./Services.module.css"
import FadeInSection from "../FadeInSection/FadeInSection"
import { SRLWrapper } from "simple-react-lightbox"
import kitchen from "../../images/GalleryImages/image1.jpg"
import bathroom from "../../images/GalleryImages/image2.jpg"
import flooring from "../../images/GalleryImages/image4.jpg"
import painting from "../../images/GalleryImages/image5.jpg"
import cabinets from "../../images/GalleryImages/image6.jpg"
import backsplash from "../../images/GalleryImages/image7.jpg"
import basement from "../../images/GalleryImages/image8.jpg"

const Services = () => {
  const [selectedInterior, setSelectedInterior] = useState(kitchen)
  const [selectedExterior, setSelectedExterior] = useState(bathroom)

  return (
    <div className={styles.container} id="services-page">
      <div className={styles.content}>
        <FadeInSection>
          <div className={styles.description}>
            <h1 className="bigTitle">What we have to offer</h1>
            <h2 className="smallTitle">
              We offer a variety of services for both the interior and exterior
              of your home
            </h2>
            <div className="line"></div>
          </div>
          <SRLWrapper>
            <section className={styles.servicesSection}>
              <div className={styles.servicesContainer}>
                <div className={styles.servicesContent}>
                  <h1 className={styles.servicesTitle}>Interior Services</h1>
                  <ul className={styles.renovationList}>
                    <li onClick={() => setSelectedInterior(bathroom)}>
                      Bathrooms
                    </li>
                    <li onClick={() => setSelectedInterior(basement)}>
                      Basements
                    </li>
                    <li onClick={() => setSelectedInterior(kitchen)}>
                      Kitchens
                    </li>
                    <li onClick={() => setSelectedInterior(cabinets)}>
                      Cabinet Installation
                    </li>
                    <li onClick={() => setSelectedInterior(painting)}>
                      Painting
                    </li>
                    <li onClick={() => setSelectedInterior(backsplash)}>
                      Backsplash
                    </li>
                    <li onClick={() => setSelectedInterior(flooring)}>
                      Flooring
                    </li>
                  </ul>
                </div>
              </div>
              <div className={styles.service}>
                <div className={styles.imageContainer}>
                  <img
                    src={selectedInterior}
                    className={styles.interiorImage}
                  />
                </div>
                <p className={styles.serviceDescription}>
                  Lorem ipsum dolor sit amet consectetur adipisicing elit. Enim
                  perferendis quibusdam ipsa fuga qui, velit non voluptatem,
                  quod, illum tempore consequuntur! Fuga fugiat odit quisquam
                  officia consequuntur, sapiente voluptatibus maxime!
                </p>
              </div>
            </section>
            <section className={styles.servicesSection}>
              <div className={styles.servicesContainer}>
                <div className={styles.servicesContent}>
                  <h1 className={styles.servicesTitle}>Exterior Services</h1>
                  <ul className={styles.renovationList}>
                    <li onClick={() => setSelectedExterior(kitchen)}>
                    Fences
                    </li>
                    <li onClick={() => setSelectedExterior(bathroom)}>
                     Decks
                    </li>
                    <li onClick={() => setSelectedExterior(flooring)}>
                      Patios
                    </li>
                    <li onClick={() => setSelectedExterior(kitchen)}>
                      Porches
                    </li>
                    <li onClick={() => setSelectedExterior(bathroom)}>
                      Siding
                    </li>
                  </ul>
                </div>
              </div>
              <div className={styles.service}>
              <div className={styles.imageContainer}>
                <img src={selectedExterior} className={styles.exteriorImage} />
              </div>
                <p className={styles.serviceDescription}>
                  Lorem ipsum dolor sit amet consectetur adipisicing elit. Enim
                  perferendis quibusdam ipsa fuga qui, velit non voluptatem,
                  quod, illum tempore consequuntur! Fuga fugiat odit quisquam
                  officia consequuntur, sapiente voluptatibus maxime!
                </p>
             </div>
            </section>
          </SRLWrapper>
        </FadeInSection>
      </div>
    </div>
  )
}

export default Services

像您建议的那样设置一个包含图像和文本的对象是一个非常合理的建议。然后,您的状态可以容纳整个对象。这是一个非常 basic/minimal 的例子,演示了它是如何工作的:

const Rooms = {
  kitchen: {
    img: "kitchenImage",
    text: "kitchenText"
  },
  bedroom: {
    img: "bedroomImage",
    text: "bedroomText"
  }
}

export default function App() {
  const [selectedRoom, setSelectedRoom] = React.useState()

  return (
    <div className="App">
      <div>
       {selectedRoom ? 
         <div>
           Image: {selectedRoom.img}<br/>
           Text: {selectedRoom.text}
         </div> 
       : null}
      </div>
      <ul>
       <li style={selectedRoom === Rooms.kitchen ? {fontWeight: "bold"} : {}} 
           onClick={() => setSelectedRoom(Rooms.kitchen)}>kitchen</li>
       <li style={selectedRoom === Rooms.bedroom ? {fontWeight: "bold"} : {}} 
           onClick={() => setSelectedRoom(Rooms.bedroom)}>bedroom</li>
      </ul>
    </div>
  );
}

开始时未选择任何内容,但您可以通过执行以下操作轻松地从默认选择开始:

... = React.useState(Rooms.bedroom)

使用此系统,您将能够根据需要向 Rooms 添加更多字段,而无需添加额外的状态变量。

根据评论更新: 我向 li 添加了一个 style 属性,该属性根据选择而变化。在一个真实世界的例子中,可能值得将 li 抽象到它自己的组件中,但以这种方式做事服务于这个最小的例子。