【问题标题】:Modal only shows last element of mapped array in React模态仅显示 React 中映射数组的最后一个元素
【发布时间】:2021-06-06 11:40:12
【问题描述】:

现在,如果用户单击按钮,我正在尝试渲染元素各自的内容。截至目前,因为一旦我按下按钮,它就会为每个元素创建一个模态,它会打开所有模态,显示最后一个。

我查看了有关此问题的先前问题,非常感谢您提供一些帮助。

例如,一旦我按下该项目卡的按钮以查看有关该项目的更多信息,它只会显示正在映射的数组的最后一个元素的信息。

const [modalIsOpen, setModalIsOpen] = useState(false)
 return (
   <>
  <Grid container
    direction="row"
    className="Project--Items" 
    xs={9} >
    {projects.map((project) => (
      <div key={project.id}className="Project--Card">
        <img src={project.image} className="Item--Main--Image"/>
        <div className="Card--Text">
          <p>{project.name}</p>
          <p>{project.description}</p>
        </div>
        <button onClick={() => setModalIsOpen(true)}>Open Modal</button>
        <Modal isOpen={modalIsOpen} onRequestClose={()=> setModalIsOpen(false)}>
          <h2>{project.name}</h2>
          <p>{project.description}</p>
          <div>
            <button onClick={() => setModalIsOpen(false)}>Close Modal</button>
          </div>
        </Modal>

      </div>
      
    ))}
  </Grid>

  </>
);
}

【问题讨论】:

  • 首先需要在map函数之外声明Modal组件,所以只有一个

标签: javascript reactjs jsx


【解决方案1】:
const [modalIsOpen, setModalIsOpen] = useState(false)
const [selectedProject, setSelectedProject] = useState(null);

const expandModal = (project) => {
    setSelectedProject(project);
    setModalIsOpen(true);
}

const closeModal = () => {
    setSelectedProject(null);
    setModalIsOpen(true);
}

 return (
  <Grid container
    direction="row"
    className="Project--Items" 
    xs={9} >
    {projects.map((project) => (
      <div key={project.id}className="Project--Card">
        <img src={project.image} className="Item--Main--Image"/>
        <div className="Card--Text">
          <p>{project.name}</p>
          <p>{project.description}</p>
        </div>
        <button onClick={() => expandModal(project)}>OpenModal</button>
      </div>
    ))}
    <Modal isOpen={modalIsOpen} onRequestClose={closeModal}>
      <h2>{selectedProject && selectedProject.name}</h2>
        <p>{selectedProject && selectedProject.description}</p>
        <div>
          <button onClick={closeModal}>Close Modal</button>
        </div>
    </Modal>
  </Grid>
);
}

【讨论】:

  • 太棒了!谢谢你们,我看到了之前发生的事情。
【解决方案2】:

这里的结构有点不稳定。您应该在所有内容之上有一个隐藏的 Modale,并简单地传递一些信息。它将避免在 dom 上渲染无数模态。

类似的东西呢:

function Modale ({isOpen, onClose, project}){
return isOpen && (
      <>
          <h2>{project.name}</h2>
          <p>{project.description}</p>
          <div>
            <button onClick={onClose}>Close Modal</button>
          </div>
        </>
}

function List (){
const [modalIsOpen, setModalIsOpen] = useState(false)
const [focusProject, setFocusProject] = useState(null)

const onOpenModale = (project) => {
  setModalIsOpen(true)
  setFocusProject(project)
}

const onCloseModale = () => {
  setModalIsOpen(false)
  setFocusProject(null)
}

 return (
   <>
   <Modale isOpen={modalIsOpen} onClose={onCloseModale} project={focusProject}/>
     <Grid container direction="row" className="Project--Items" xs={9} >
        {projects.map((project) => (
          <div key={project.id} className="Project--Card">
            <img src={project.image} className="Item--Main--Image"/>
            <div className="Card--Text">
            <p>{project.name}</p>
            <p>{project.description}</p>
            </div>
          <button onClick={()=> onOpenModale(project)}>Open Modal</button>
         </div>
       ))}
     </Grid>
  </>
);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    • 2012-01-27
    • 1970-01-01
    • 2018-10-30
    • 2020-09-14
    • 2021-08-18
    • 2017-08-24
    相关资源
    最近更新 更多