如何解决 React Bootstrap 模态框无法正确显示关闭动画的问题?

新手上路,请多包涵

我按照 ChatGPT 的描述,在 React Bootstrap 模态框的基础上以 hook 的形式封装了一个消息框组件,代码如下:

import React from "react";
import { useState, createContext, useRef } from "react";
import { Button, Modal } from "react-bootstrap";

function useMessageBox() {
    let [title, setTitle] = useState('');
    let [message, setMessage] = useState('');
    let [buttons, setButtons] = useState(null);

    let [showDialog, setShowDialog] = useState(false);
    let resolveRef = useRef(null);

    const handleResult = (result) => {
        console.log(result);
        resolveRef.current(result);
        setShowDialog(false);
    };

    const MessageBox = () => {
        return (
            <div>
                <Modal show={showDialog}>
                    <Modal.Header>
                        <Modal.Title>{title}</Modal.Title>
                    </Modal.Header>
                    <Modal.Body>{message}</Modal.Body>
                    <Modal.Footer>
                        {buttons}
                    </Modal.Footer>
                </Modal>
            </div>
        );
    };

    const show = (title, message, type) => {
        setTitle(title);
        setMessage(message);
        if (type === 'ok') {
            setButtons(
                <Button variant="primary" onClick={ () => handleResult('ok') }>确定</Button>
            );
        }
        else if (type === 'yesno') {
            setButtons(
                <>
                    <Button variant="secondary" onClick={ () => handleResult('confirm') }>取消</Button>
                    <Button variant="primary" onClick={ () => handleResult('cancel') }>确定</Button>
                </>
            )
        }

        setShowDialog(true);

        return new Promise((resolve, reject) => {
            resolveRef.current = resolve;
        });
    };

    return [MessageBox, show];
}

export default useMessageBox;

调用:

function App() {
  const [MessageBox, show] = useMessageBox();

  return (
    <div>
      <h1>123</h1>
      <Button onClick={() => show("标题", "123", "yesno")}>显示</Button>
      <Button onClick={() => show("标题", "456", "ok")}>显示2</Button>
      <MessageBox />
    </div>
  );
}

目前的问题是关闭对话框的时候没有动画,这个怎么解决?
CodeSandbox 链接

阅读 1k
avatarAI BotBETA

关闭动画缺失的问题通常与 React Bootstrap Modal 组件的样式或状态管理有关。在你的代码中,你使用了自定义的钩子和状态来控制 Modal 的显示和隐藏。这里有一些可能的解决方案:

1. 确保正确引用了 Bootstrap CSS

确保你的项目中已经正确引用了 Bootstrap 的 CSS 文件。如果没有正确引用,Modal 的样式(包括动画)可能无法正确显示。

<!-- 在你的 HTML 文件的 <head> 中添加 Bootstrap CSS 引用 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ06o3xD/rE3zearns5qnwN" crossorigin="anonymous">

2. 检查 React Bootstrap Modal 组件的 animation 属性

确保 Modal 组件的 animation 属性被设置为 true。虽然这个属性在 React Bootstrap 的文档中不是必需的(默认是开启的),但确认一下总是好的。

<Modal show={showDialog} animation={true}>
  {/* ... */}
</Modal>

3. 使用 React 的状态更新来控制 Modal 的显示和隐藏

在你的代码中,你使用了 setShowDialog(true) 来显示 Modal,并通过一个 Promiseresolve 来关闭它。确保在关闭 Modal 时(即调用 setShowDialog(false))React 的状态更新是异步的,以便有足够的时间进行动画渲染。

通常,React 的状态更新应该是响应式的,并且会触发组件的重新渲染。但如果你的代码中有其他逻辑(如立即的 Promise resolve)干扰了状态更新的流程,这可能会影响到动画的播放。

4. 调试和审查网络请求

有时,网络请求或外部资源的加载可能会影响到页面的渲染和动画效果。检查浏览器的开发者工具中的网络请求,确保没有阻塞或延迟加载的资源。

5. 检查其他 CSS 或 JavaScript 冲突

如果你的项目中还有其他 CSS 或 JavaScript 代码,确保它们没有影响到 Modal 的样式或行为。例如,全局的 CSS 重置或 JavaScript 事件处理器可能会干扰 Modal 的正常显示和关闭动画。

如果上述方法都不能解决你的问题,建议进一步审查你的代码,并查看 React Bootstrap 的文档和社区,看看是否有其他开发者遇到并解决了类似的问题。此外,确保你的 React Bootstrap 版本是最新的,或者至少是一个稳定的版本,因为旧版本可能包含已知的 bug。

1 个回答
✓ 已被采纳

MessageBox_Hook.js:

const MessageBox = useMemo(() => {
  return (
    <div>
      <Modal show={showDialog}>
        <Modal.Header>
          <Modal.Title>{title}</Modal.Title>
        </Modal.Header>
        <Modal.Body>{message}</Modal.Body>
        <Modal.Footer>{buttons}</Modal.Footer>
      </Modal>
    </div>
  );
});

App.js

return (
  <div>
    <h1>123</h1>
    <Button onClick={() => show("标题", "123", "yesno")}>显示</Button>
    <Button onClick={() => show("标题", "456", "ok")}>显示2</Button>
    {MessageBox}
  </div>
);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题