【问题标题】:Cannot read properties of null (reading 'defaultPrevented') in bootstrap 5 toast无法在引导程序 5 toast 中读取 null 的属性(读取“defaultPrevented”)
【发布时间】:2021-12-23 08:44:07
【问题描述】:

使用自定义挂钩显示和隐藏 toast,当在外部使用此挂钩时,在 Toast 组件按钮中调用 showTost 时,它可以正常工作,即在 App 组件按钮中出现错误

TypeError
Cannot read properties of null (reading 'defaultPrevented')
Toast.show
https://izso9.csb.app/node_modules/bootstrap/dist/js/bootstrap.esm.js:3399:19
showToast
/src/useToast.js:11:12
   8 | 
   9 |  const showToast = () => {
  10 |    bsToast = new Toast(myToast, { autohide: true, delay: 1000 });
> 11 |    bsToast.show();
     |           ^
  12 |  };
  13 | 
  14 |  const hideToast = () => {
View compiled

使用Toast.js

import { Toast } from "bootstrap";
import { useRef } from "react";

export default function useToast() {
  const toastRef = useRef();
  let myToast = toastRef.current;
  let bsToast = Toast.getInstance(myToast);

  const showToast = () => {
    bsToast = new Toast(myToast, { autohide: true, delay: 1000 });
    bsToast.show();
  };

  const hideToast = () => {
    bsToast = new Toast(myToast, { autohide: true });
    bsToast.hide();
  };
  return { toastRef, showToast, hideToast };
}

CODE SANDBOX LINK

【问题讨论】:

  • 单击任一按钮时,我看到同样的错误。

标签: javascript reactjs react-hooks bootstrap-5


【解决方案1】:

那是因为您没有从 App 组件传递 toastRef 并且它是未定义的。如果你在 App 组件中添加这段代码,它就可以工作了

<div
    className="toast position-absolute bottom-0 end-0 m-4"
    role="alert"
    ref={toastRef}
  >
    <div className="toast-header">
      <strong className="me-auto">Bootstrap 5</strong>
      <small>4 mins ago</small>
      <button
        type="button"
        className="btn-close"
        onClick={hideToast}
        aria-label="Close"
      ></button>
    </div>
    <div className="toast-body">Hello, world! This is a toast message.</div>
  </div>

【讨论】:

  • 如果我想根据 api 状态码对任何成功响应调用 toast ,我该怎么做?
  • 这是一个广泛的问题。这将取决于您的实现,所以我无法回答,但可以肯定的是,您必须抽象出 toast 组件并在任何您想要的地方调用它
【解决方案2】:

我在 Vuejs 中使用了 bootstrap 5 并且遇到了同样的错误。我发现在一个地方(在组件创建时)创建 Toast 并且我在另一个地方(在组件更新时)调用 toast.show() 时会出现相同的错误。

示例如下:

export default {
  props: {
     toastHeader: String,
     toastBody: String,
     isHidden: Boolean
 }, 
 data() {
     return {
         toast: null
     }
 },
 created(){
     //here toast initialized when component is created
     this.toast = new Toast(document.getElementById("bootstrap-toast"));
 },
 updated(){
     //component is updated, so toast is recreated in DOM. Error thrown
     if(!this.isHidden) this.toast.show();
 }  
}

为了解决这个问题,我做了以下事情:

export default {
  props: {
      toastHeader: String,
      toastBody: String,
      isHidden: Boolean
  },
  updated(){
      let toast = new Toast(document.getElementById("bootstrap-toast"));
      if(!this.isHidden) toast.show();
  }  
}

可能在您的情况下,也有相同的情况。因此,toastRef.current 可能在触发 toast 显示/隐藏时包含无效的内容。尝试在 new Toast() 中使用 document.getElementById 来检查它是否与我的情况完全相同。我知道使用 document.getElementById 似乎很奇怪。至少它会让你知道问题出在哪里。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-26
    • 2021-11-28
    • 2022-01-12
    • 2021-12-04
    • 2022-01-06
    • 2021-11-14
    相关资源
    最近更新 更多