如何防止重复弹出模态(&A)不滚动到ReactJS中的最后一个元素

我正在创建一个项目,在该项目中,我使用map()从服务器获取数据,并使用10呈现10不同Bootstrap卡中的数据。每张卡都有一个弹出模态的按钮。在我旁边,我设置了一个LinkTO按钮,它将向我显示数据路由。

信息

  • 对模式使用react-bootstraphooks
  • 使用react-router-dom显示route
  • 使用useState挂钩将提取数据中的数据设置为模式。
  • 所有代码都在一个组件中。
  • info_prop&;info不同,但使用相同的数据。
  • 我已经import所有需要的东西&&;没有任何warning or error
  • 关于数据处理
    • 首先我使用chapterId通过useGetDataQuery()获取数据。
    • 映射数据&;解析info数据&;设置为状态为setInfo
    • 使用info发送到模态道具
    • 使用handleModal发送到setInfo的句柄。我也试了一下,没有这个功能。那次我是在onClick做的。

问题

  • MAP()的路由问题
    • 我使用Button显示Modal&;用Link包装按钮。每个Link都有一个像1:1, 1:2, 1:3...1:10这样的唯一ID。如果我单击1:1按钮,它会显示1:1内容。但是当我关闭模式时,路线自动更改为1:11:3...1:10
    • 我可以意识到它在mainModal后面呈现了一个副本Modal。我只能看到3-4行后模态。
  • 模态问题
    • 当我用弹出模式的MAP&;点击按钮显示1-5个数据时,模式显示正常,背景模糊。
    • 当我用弹出模式的地图&;点击按钮演示1-10数据时,背景变成纯黑色。(我觉得这不正常)

依赖项

  • Reaction-Bootstrap v5
  • Bootstrap v5
  • REACT-ROUTER-DOM v6

代码

  • 组件代码。Modal在同一组件中,但在另一个函数中。
function TafsirModal(props) {
    return (
        <Modal
            {...props}
            size="md"
            aria-labelledby="contained-modal-title-vcenter"
            centered
        >
            <Modal.Header closeButton>
                <Modal.Title id="contained-modal-title-vcenter">
                    Heading
                </Modal.Title>
            </Modal.Header>
            <Modal.Body>
                <div>
                    {props.info}
                </div>
            </Modal.Body>
            <Modal.Footer>
                <Button onClick={props.onHide}>Close</Button>
            </Modal.Footer>
        </Modal>
    )
}

const InfoCom = () => {
    const { chapterId } = useParams()

    let [modalShow, setModalShow] = useState(false);
    let [info, setInfo] = useState('')
    const { data } = useGetDataQuery(chapterId)


    const handleModal = (info_prop) => {
        setInfo(info_prop)
        setModalShow(true)
    }

    return (
        <>
            <div className="container">
                <div className="row">
                    <div className="col-md-12">
                        {data.map(res => (
                            <Link to={`/li/${chapterId}/${res.res_key}`} key={res.res_key} >
                                <div key={res.id} className='card my-2'>
                                    <div className="card-body">
                                        <div className="d-flex flex-row">
                                            <Button onClick={() => handleModal(res.info[0].text)}>
                                                Get Info
                                            </Button>

                                            <TafsirModal
                                                show={modalShow}
                                                onHide={() => setModalShow(false)}
                                                info={info}
                                            />
                                        </div>
                                    </div>
                                </div>
                            </Link>
                        ))}
                    </div>
                </div>
            </div>
        </>
    )
}
export default InfoCom


解决方案

问题看起来像是您使用显示模式的处理方式 show={modalShow} 每当您单击一个按钮来显示您的模式时,它们都会显示,因为它们都从modalShow中显示了show mode true。不使用showModal状态,请尝试执行以下操作:

let [activeModal, setActiveModal] = useState('');

function handleModal(info_prop) {
  setInfo(info_prop)
  // if you have an id or something use that instead of text in set activeModal
  setActiveModal(info_prop)
}
// in map
<Button onClick=(() => handleModal(res.info[0].text)></Button>

<TafsirModal
  show={activeModal === res.info[0].text ? true : false}
  onHide=(setActiveModal(''))
/>
我更常用的另一个解决方案是将模型呈现在映射之外的组件顶层,这样您就可以使用与当前相同的逻辑,这样我们就只呈现一个模型,我认为这样会更好,也更容易阅读。 我们只需在树中向上移动<TafsirModal />几个级别就可以做到这一点

<>
            <div className="container">
                <div className="row">
                    <div className="col-md-12">
                        {data.map(res => (
                            <Link to={`/li/${chapterId}/${res.res_key}`} key={res.res_key} >
                                <div key={res.id} className='card my-2'>
                                    <div className="card-body">
                                        <div className="d-flex flex-row">
                                            <Button onClick={() => handleModal(res.info[0].text)}>
                                                Get Info
                                            </Button>
                                        </div>
                                    </div>
                                </div>
                            </Link>
                        ))}
                    </div>
                </div>
               {activeModal && <TafsirModal
                  show={modalShow}
                  onHide={() => setModalShow(false)}
                  info={info}
                 />
                }
            </div>
        </>

相关文章