如何为每个按钮映射制作打开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} />
...

其中CCD_ 6和CCD_。我尝试了很多不同的东西,并引用了这4篇StackOverflow帖子,但它们使用类,我不确定如何用钩子复制所需的效果:

  • ReactJS:只打开地图项目的选定模式弹出窗口
  • 通过onClick事件打开特定组件-REACT.JS
  • .map中的多模态
  • React-通过单击事件在映射函数内渲染项

尝试将模态切换到使用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关于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===name(:

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>
</>
)
}

分享这个是因为我希望我有这样详细的东西。希望这对你们中的一些人有所帮助!

最新更新