有什么方法可以在不显式存储状态的情况下打开模态对话框?

Any way to open a modal dialog without explicitly storing state?

我最近一直在使用react-modal,显示模态的模式是这样的:

const [modalIsOpen, setModalIsOpen] = useState(false);
return (<ModalDialog isOpen={modalIsOpen}><div>some content</div></ModalDialog>)

...感觉非常 React-y,但过于冗长。有没有办法在我可以的地方启用某些东西 - 在点击处理程序中 - 只需调用:

showModal(MyComponent)

并自动处理状态?我考虑过在应用程序周围创建一个上下文,允许 showModal 获取与 MyComponent 关联的状态,在这种情况下,这本身就是一个钩子,因此它必须遵循某些规则(即,没有条件调用),所以我不确定我能否让它像我想要的那样干净地工作。

有没有办法在 React 生态系统中做到这一点?还是我应该放弃并使用现有机制?

是的!您可以使用“渲染”功能来完成。

不幸的是,它在 CodeSandBox 中不起作用,但您可以从这里 fork 它: https://github.com/BHVampire/modal

You close the modal by clicking outside.

我是这样做的:

最后,您将能够从应用程序的任何部分打开这样的模式:

createModal(<h1>Success</h1>)

首先,您在 App 组件之外为您的模式添加一个容器,因此您永远不会遇到 z-index 问题:

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import './index.scss'
import App from './App.jsx'

ReactDOM.render(
  <React.StrictMode>
    <div id="modal-container"></div> <- This is the container
    <App />
  </React.StrictMode>,
  document.getElementById('root')
)

app.jsx

import createModal from "./components/Modal"

const App = () => {
  return <button onClick={() => createModal(<h1>Success</h1>)}>Open Modal</button>
}

export default App

然后我在模态文件夹 + 样式中有模态的 2 个主要文件。

Modal/index.js

状态挂钩对于模式来说是不可避免的,但你再也见不到了。

import { Fragment, useState } from 'react'
import './Modal.scss'

const Modal = ({ content }) => {
    const [isOpen, setIsOpen] = useState(true)

    return isOpen
        ? <Fragment>
            <div onClick={() => setIsOpen(false)} className="modal-background" />

            <div className="modal" >
                {content}
            </div>
        </Fragment>
        : ''
}

export default Modal