将图像动态渲染为模态形式映射的图像数组

Dynamically rendering images into modal form mapped array of images

我正在做一个项目,最近才开始 React.So 到目前为止,我制作了卡片组件,该组件动态渲染来自 js 文件的数据,映射的 function.One 正在渲染的数据是(存储在数组中)图像,其中我显示第一个 img 并设置一个打开模态的 onClick 函数。

这就是我 stuck.Modal 使用非目标 img 打开的地方,我想首先在模态中显示点击的图像,然后传递该数组中可以点击的其余图像 through.Like 一张图片 slider.When 我 console.log 我能看到的图片 我正在获取模态中的所有数组,但我不知道如何相应地设置它们。

如果能提供一些解决问题的方法以及我做错了什么,我将不胜感激。

我有一个从 js 文件接收数据的父组件。

class Room extends Component{
  constructor(){
    super();
    this.state = {
      data: roomData,
    }
  }

    render(){
      return (
        <>
          <div>helo from room page</div>
          <RoomCards  data={this.state.data} />
        </>
        
      );
    }
}

这是卡片组件

import Modal from "../components/modal";



class RoomCards extends Component{
constructor(){
  super();

  this.state = {
    showModal: false,
  
  };

}

getModal = ()=> {
  this.setState({ showModal: true })
}
hideModal = () => {
  this.setState({ showModal: false });
} 


render(){
  return (
    <>
      {
        this.props.data.map((data) => {
          return <div className="card__container" key={data.id} >
                    <div className="card">
                      <h2 className="card__title">{data.name}</h2>
                        <p className="card__description">{data.paragraph}</p>
                          <ul><li>{data.list[0]}</li></ul>
                          <ul><li>{data.list[1]}</li></ul>
                          <ul><li>{data.list[2]}</li></ul>
                          <ul><li>{data.list[2]}</li></ul>

                          <div  className="card__img">
                          <img src={data.image} 
                          onClick={() => this.getModal(data)} 
                          alt="" />

                          <Modal 
                            show={this.state.showModal}
                            onHide={() => this.hideModal()}
                            image={data.image} />
                          </div>
                    </div>
                    <button className="card__btn">Bestill overnatting</button>
                  </div>
          })  
        }
    </>
    )
  }
}
export default RoomCards

模态组件

import React, { Component } from "react";
import  "../styles/Room.scss";

class Modal extends Component {
  constructor(){
  super();

  this.state = {
      index:0
  };
}


  next =() => { 
    if({index : this.state.index}){
      this.setState({index: this.state.index + 1});
    }else {
      this.setState({index: this.state.index})
      console.log("heloo i am at index");
  }
}

  prev=()=>{
    if(this.state.index === 0 || this.state.index === -1) {
        console.log("hi")
      }else {
        this.setState({index :this.state.index - 1});
        }
    }



  render() {
    console.log(this.props.image)
    return (
      <React.Fragment>
        {this.props.show && (
          <div className="modal">
            <img alt="" src={this.props.image[this.state.index]} key={this.state.index} />
              {/* <img alt="" src={this.props.image[1]}/> */}
        
            <button onClick={this.props.onHide}>Close Modal</button>
            <button onClick={this.prev}></button>
            <button onClick={this.next}></button>  
          </div>
        )}
      </React.Fragment>
    );
  }
}

export default Modal;

和来自 js 文件的数据


const roomData = [
  {
    id:1,
    name: "standard room something new",
    paragraph:"Hotellets standard enkeltrom passer perfekt til deg som reiser alene. Rommene er møblert med enten en 90 cm seng eller en 160 cm bred seng, skrivebord, lenestol, og baderom med dusj ",
    list: ["wifi", "tv", "ikke royken"],
    image: ['https://images.unsplash.com/photo-1585255318859-f5c15f4cffe9?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=500&ixlib=rb-1.2.1&q=80&w=500',
            'https://images.unsplash.com/photo-1584226761916-3fd67ab5ac3a?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=500&ixlib=rb-1.2.1&q=80&w=500',
            'https://images.unsplash.com/photo-1585084335487-f653d0859c14?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=500&ixlib=rb-1.2.1&q=80&w=500',
            'https://images.unsplash.com/photo-1583217874534-581393fd5325?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=500&ixlib=rb-1.2.1&q=80&w=500',
          ]
  },
    
    {
    id:2,
    name: "standard room something new",
    paragraph:"Hotellets standard enkeltrom passer perfekt til deg som reiser alene. Rommene er møblert med enten en 90 cm seng eller en 160 cm bred seng, skrivebord, lenestol, og baderom med dusj ",
    list:  ["wifi","tv", "ikke royken"],
    image: ['https://images.unsplash.com/photo-1585179292338-45ba1f62f082?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=500&ixlib=rb-1.2.1&q=80&w=500',
            'https://images.unsplash.com/photo-1584753987666-ead137ec0614?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=500&ixlib=rb-1.2.1&q=80&w=500',
            'https://images.unsplash.com/photo-1583217874534-581393fd5325?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=500&ixlib=rb-1.2.1&q=80&w=500',]
  },
    {
    id:3,
    name: "standard room something new",
    paragraph:"Hotellets standard enkeltrom passer perfekt til deg som reiser alene. Rommene er møblert med enten en 90 cm seng eller en 160 cm bred seng, skrivebord, lenestol, og baderom med dusj ",
    list: ["wifi", "tv", "ikke..."],
    image:['https://images.unsplash.com/photo-1584691267914-91c0bee55964?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=500&ixlib=rb-1.2.1&q=80&w=500',
            'https://images.unsplash.com/photo-1585084335487-f653d0859c14?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=500&ixlib=rb-1.2.1&q=80&w=500']
  },
    {
    id:4,
    name: "standard room something new",
    paragraph:"Hotellets standard enkeltrom passer perfekt til deg som reiser alene. Rommene er møblert med enten en 90 cm seng eller en 160 cm bred seng, skrivebord, lenestol, og baderom med dusj ",
    list: ["wifi", "tv,"],
    image: ['https://images.unsplash.com/photo-1583217874534-581393fd5325?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=500&ixlib=rb-1.2.1&q=80&w=500']
  }
]
export default roomData;

这里的主要问题是,您正在为映射的每个 data 元素呈现模式,但使用最终切换 all 的单个 showModal 状态 个 open/close 在一起。

我建议将你想在模式中显示的具体数据存储到state.showModal状态,初始值null。有条件地渲染单个 Modal 组件。

class RoomCards extends Component {
  state = {
    showModal: null
  };

  getModal = (data) => {
    this.setState({ showModal: data });
  };
  hideModal = () => {
    this.setState({ showModal: null });
  };

  render() {
    return (
      <>
        {this.props.data.map((data) => {
          return (
            <div className="card__container" key={data.id}>
              <div className="card">
                <h2 className="card__title">{data.name}</h2>
                <p className="card__description">{data.paragraph}</p>
                <ul>
                  {data.list.map((item) => (
                    <li key={item}>{item}</li>
                  ))}
                </ul>

                <div className="card__img">
                  <img
                    src={data.image}
                    onClick={() => this.getModal(data)}
                    alt=""
                  />
                </div>
              </div>
              <button className="card__btn">Bestill overnatting</button>
            </div>
          );
        })}

        {this.state.showModal && (
          <Modal
            onHide={this.hideModal}
            images={this.state.showModal?.image}
          />
        )}
      </>
    );
  }
}

修复模态以保持有效的当前索引值。

class Modal extends Component {
  state = {
    index: 0
  };

  next = () => {
    const { images } = this.props;
    this.setState(({ index }) => ({
      index: Math.min(images.length - 1, index + 1)
    }));
  };

  prev = () => {
    this.setState(({ index }) => ({
      index: Math.max(0, index - 1)
    }));
  };

  render() {
    const { index } = this.state;
    const { images, onHide } = this.props;
    return (
      <div className="modal">
        <img alt="" src={images[index]} />

        <button onClick={this.props.onHide}>Close Modal</button>
        <button onClick={this.prev}></button>
        <button onClick={this.next}></button>
      </div>
    );
  }
}