如何制作为每个按钮图打开onClick的模态图?

问题描述

我目前有如下功能组件,其中 从useValues()生成几个按钮。

const ButtonsWithModals = () => {
  const [objects,loading] = uSEObjects() // `loading` is used in my `App` HOC
  const [isModalOpen,setModalOpen] = React.useState()
  const [modal,setModal] = React.useState([])
  
  const ref = React.useRef()
  
  function onClickOutside() {
    setModalOpen(false)
  }
  
  useClickOutside(ref,onClickOutside)
  
  return (
    <>
      {isModalOpen ? (
        <RenderModal ref={ref} key={modal} objectValue3={object.value3} />
        ) : (
        objects.map((object,index) => (
          <button
            style={{size: "" + object.value3}} 
            onClick={() => setModalOpen(true) setModal(index)}
          >
            <p>{object.value2}</p>
          </button>
        ))
        )
      }
    </>
  )
}

useVObjects()钩子获取并返回我使用values.map((object,index) {...})渲染为按钮的对象列表。

当我尝试呈现用户单击的特定按钮所独有的模式时,我的奋斗就出现了。

这是我的<RenderModal/>组件逻辑的样子:

const RenderModal = ({ref,key,objectValue}) => {
  
  return (
    <>
      <div class="modal">
        <div ref={ref} key={key}>
          <p>{objectValue}</p>
        </div>
      </div>
    </>
  )
}

打开模态时,我想让我的RenderModal组件根据单击哪个按钮来显示对象的信息,如下所示:

{isModalOpen ? (
        <RenderModal ref={ref} key={modal} objectValue3={objects.value3} />
        ...

其中objectValue3objects.value3根据用户单击的按钮而变化。 我已经尝试了许多不同的方法,并且一直在引用这4个StackOverflow帖子,但是它们使用类,而且我不确定如何使用钩子复制所需的效果

解决方法

尝试将Modal切换到使用Context API的组件。这是一个示例,允许您传入用于模态内容以及任何其他道具的组件。

https://codesandbox.io/s/modal-context-api-7yk3b

import { useModal } from "../Modal";

const ModalEnglishContent = (props) => <div>Hello,{props.name}!</div>;
const ModalGermanContent = (props) => <div>Guten Tag,{props.name}!</div>;
const ModalSpanishContent = (props) => <div>Buenos días,{props.name}</div>;

const Example = () => {
  const { showModal } = useModal();

  function showModalEnglish() {
    showModal(ModalEnglishContent,{ name: "Sam" });
  }

  function showModalGerman() {
    showModal(ModalGermanContent,{ name: "Gunter" });
  }

  function showModalSpanish() {
    showModal(ModalSpanishContent,{ name: "Jose" });
  }

  return (
    <section>
      <header>
        <h1>Example</h1>
      </header>
      <button onClick={showModalEnglish}>Show English Modal</button>
      <button onClick={showModalGerman}>Show German Modal</button>
      <button onClick={showModalSpanish}>Show Spanish Modal</button>
    </section>
  );
};

export default Example;
,

我最终要做的是快速又肮脏的事情。我认为,在回顾了Robin Wieruch的tutorial on React CSS之后,有一种实现我想要实现的目标的最佳方法。

这是我主要的带有钩子的CardsAndModals功能组件逻辑:

const CardsAndModals = () => {
  const [objects] = useObjects()

  const [isModalOpen,setModalOpen] = React.useState(false)
  const [modal,setModal] = React.useState(null)
  
  /* Lists of property values for each object */
  let objectValues1 = objects.map(object => object.value1)
  let objectValues2 = objects.map(object => object.value2)
  let objectValues3 = objects.map(object => object.value3)
  let objectValues4 = objects.map(object => object.value4)
  
  // used when calling `useClickOutside()` hook
  const ref = React.useRef()  
  
  function onClickOutside() {
    setModalOpen(false)
  }
  
  function handleOnClick(index) {
    setModalOpen(true)
    setModal(index)
  }
 
  useClickOutside(ref,onClickOutside)
  
  return (
    <>
      {objects.map((object,index) => (
        <button
          class="card" 
          style={{size: "" + object.value3}} 
          onClick={() => handleOnClick(index)}
        >
          <p>{object.value1}</p>
          <p class="helper-text">Click for more info!</p>
        </button>
      ))
      }
      {isModalOpen && setModal != null ? (
        <RenderModal 
          ref={ref} 
          key={modal} 
          objectValue1={objectValues1[modal]}
          objectValue2={objectValues2[modal]}
          objectValue3={objectValues3[modal]}
          objectValue4={objectValues4[modal]}
        />
      ) : (
        ""  
      )}
    </>
  )
}

最后,这是我重构的RenderModals功能组件(假设objectValue1 ===名称):

const RenderModal = ({ref,key,objectName,objectValue2,objectValue3,objectValue4,objectParagraph}) => {
  return (
    <>
      <div class="modal-backdrop">
          <div class="modal-content" ref={ref} key={key}>
            <h1 class="object-info-header">
              {objectName}
            </h1>
            <p class="object-info-value2">
              value2: {objectValue2}
            </p>
            <p class="object-info-value3">
              value3: {objectValue3}
            </p>
            <p class="object-info-value4">
              value4: {objectValue4}
            </p><br />
            <div class="object-info-paragraph">
              <p>
                Here could hold more info about the object 
                <strong>{" " + objectName}</strong>,pulled from another API (e.g.,Wikipedia):
              </p><br />
              <p>Did you know?</p>
              <p>
                <em>
                  Lorem ipsum dolor sit amet,consectetur adipiscing
                  elit. Curabitur in viverra turpis. Vivamus id
                  pretium sapien,eu rhoncus ligula. Nam magna ante,viverra ac neque at,volutpat finibus arcu. 
                  Pellentesque at rutrum lacus. Vivamus efficitur,urna quis pulvinar vehicula,ligula justo mollis 
                  dolor,vitae lacinia lectus erat at purus. Duis 
                  ac tortor nunc. Etiam nulla lacus,posuere sit 
                  amet lectus eu,pellentesque iaculis ipsum. 
                  Curabitur vel velit commodo,vestibulum mi a,imperdiet dui.
                </em>
              </p>
            </div>
          </div>
      </div>
    </>
  )
}

分享这个是因为我希望我能详细介绍一下。希望对您有所帮助!