What could be causing the malfunction of the Bootstrap5 modal hide feature?

Today, I am facing an issue with hiding the Bootstrap5 modal in a TypeScript function. Despite trying to invoke the hide function on the modal element, it does not work as expected. Here is the minimal code snippet to reproduce this problem:

import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import * as bootstrap from 'bootstrap';

const App: React.FC = () => {

  const handleModal = (show: boolean, modalId: string) => {
    let modal = document.getElementById(modalId);
    if (modal) {
      var myModal = new bootstrap.Modal(modal);
      show ? myModal.show() : myModal.hide();

      myModal.hide();
    }
  }

  return (
    <div>
      <button onClick={() => { handleModal(true, "deleteFileModal") }}>show</button>
      <div>
        <div className="modal fade" id="deleteFileModal" aria-labelledby="deleteModalLabel" aria-hidden="true">
          <div className="modal-dialog">
            <div className="modal-content">
              <div className="modal-header">
                <h5 className="modal-title" id="deleteModalLabel">Title</h5>
                <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
              </div>
              <div className="modal-body">
                ...
              </div>
              <div className="modal-footer">
                <button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                <button type="button" className="btn btn-primary" >Confirm</button>
              </div>
            </div>
          </div>
        </div>
      </div>

    </div>
  );
}

export default App;

Despite calling the modal hide function at the end, the modal still did not hide properly. What am I missing here? How can I resolve this issue? In my project, the hide method is used like this:

const handleOk = () => {
        let params = {
            name: createFileName,
            project_id: pid,
            parent: pid,
            file_type: 1
        };
        addFile(params).then((resp) => {
            if (ResponseHandler.responseSuccess(resp)) {
                handleModal(false,"createFileModal");
                getFileList(pid?.toString());
            }
        });
    };

The modal handling function is defined as follows:

 const handleModal = (show: boolean, modalId: string) => {
        let modal = document.getElementById(modalId);
        if (modal) {
            var myModal = new bootstrap.Modal(modal);
            show ? myModal.show() : myModal.hide();
        }
    }

Unfortunately, the modal closure is not successful.

Answer №1

Check out this updated version of your handleModal function that aims to solve the mentioned issues:

import React, { useRef, useEffect } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import * as bootstrap from 'bootstrap';

const App: React.FC = () => {
const modalRef = useRef<HTMLDivElement | null>(null);
const myModalRef = useRef<bootstrap.Modal | null>(null);

const handleModal = (show: boolean) => {
if (modalRef.current) {
  if (!myModalRef.current) {
    myModalRef.current = new bootstrap.Modal(modalRef.current);
  }

  if (show) {
    myModalRef.current.show();
  } else {
    myModalRef.current.hide();
  }
}
};

useEffect(() => {
// Clean up modal instance when component unmounts
return () => {
  if (myModalRef.current) {
    myModalRef.current.dispose();
    myModalRef.current = null;
  }
};
}, []);

return (
<div>
  <button onClick={() => handleModal(true)}>Show</button>
  <button onClick={() => handleModal(false)}>Hide</button>
  <div>
    <div className="modal fade" ref={modalRef} id="deleteFileModal" aria-labelledby="deleteModalLabel" aria-hidden="true">
      <div className="modal-dialog">
        <div className="modal-content">
          <div className="modal-header">
            <h5 className="modal-title" id="deleteModalLabel">Title</h5>
            <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
          <div className="modal-body">
            Modal content goes here...
          </div>
          <div className="modal-footer">
            <button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
            <button type="button" className="btn btn-primary">Confirm</button>
          </div>
        </div>
      </div>
    </div>
  </div>
 </div>
);
}

 export default App;

I've utilized the useRef hook to keep track of the modal element reference. The useEffect hook ensures proper cleanup of the modal instance upon component unmounting. We're fetching the existing instance of the modal using bootstrap.Modal.getInstance and performing a dispose action for appropriate cleanup.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I'm having trouble accessing my namespace in TypeScript because it hasn't been properly

After obtaining Visual Studio Community 2015 along with Node.js Tools, I decided to create a "Blank Node.js Console Application" Typescript project. Within this project, I added another TypeScript file named TypeScript1.ts. In this file, I defined the fol ...

The 'xxx' type is lacking various properties compared to the 'xxx[]' type, such as length, pop, push, concat, and many others

Utilizing typescript and reactjs, the issue lies within this component import type { InputProps } from "../utils/types" const Input = (props: InputProps) => { const makeChildren = () => { return ( <> ...

Leveraging CDK Context Variables in C# Lambda Initialization Code

I have a .NET Lambda function written in C# that is implemented as a .NET Minimal API according to the guidance provided here. To define AWS resources, I am utilizing CDK (TypeScript). Within my build pipeline, there is shell scripting involved to supply ...

Using the slice pipe on the data for a child component property is resulting in endless calls to the @Input set method

After incorporating a slice pipe into the data object below and passing that data to the child component's @Input method, there appears to be an endless loop of calls to that method. However, eliminating the slice pipe from the data object resolves th ...

Encountering an issue with Typescript and SystemJS: Struggling to locate a

After developing a module, I decided to move it out of the app and into node_modules. However, I encountered an error error TS2307: Cannot find module 'bipartite-graph'.. In this case, bipartite-graph is actually my own module. Here is the conte ...

Tips for dealing with strong reference cycles in TypeScript?

I have created a tree-like structure in my implementation, consisting of parent and child objects. The parents contain a list of children while the children have references to their parents, facilitating easy navigation through the tree. I am now contempla ...

Tips on retrieving enum values in typescript

Having trouble retrieving values from an enum? Check out this snippet of code: export const enum ComplianceType { ENGINEER_ASSESMENT = 'ENGINEER_ASSESMENT', CONSTRUCTION_COMPLIANCE = 'CONSTRUCTION_COMPLIANCE', ARCHITECTURE_ASSIGN ...

Implementing a feature in ReactJS that allows users to upload multiple images in base64 format

I'm trying to develop an image uploader using base64 and I want the output as an array. However, I am encountering an issue where the array is coming out empty!. I suspect it might be due to an asynchronous problem. Any tips on how to incorporate asyn ...

Removing fields when extending an interface in TypeScript

Attempting to extend the ISampleB interface and exclude certain values, like in the code snippet below. Not sure if there is an error in this implementation export interface ISampleA extends Omit<ISampleB, 'fieldA' | 'fieldB' | &apos ...

Subscribing to ngrx store triggers multiple emissions

Currently, I have an app with a ngrx store set up. I am experiencing an issue where, upon clicking a button, the function that fetches data from the store returns multiple copies of the data. Upon subsequent clicks, the number of returned copies grows expo ...

The function 'makeDecorator' does not support function calls when being accessed

Resolved by @alexzuza. Check out his solution below - major props! The issue was with the node_modules folder in the ng2-opd-popup directory, it needed to be removed and the src/tsconfig.app.json file had to be adjusted accordingly. Make sure to also refer ...

The Vercel/NextJS deployment does not delay the completion of the serverless function until the email is sent via Azure

Upon a user's registration, I am attempting to send a registration/account activation email. While the email sends successfully via Azure's email services when running on localhost, deployments on Vercel do not trigger the email (although the use ...

Learn the art of bypassing TypeScript errors using @ts-ignore!

I recently encountered an issue when trying to import a pure JavaScript library into a TypeScript project, resulting in the error message: Could not find a declaration file for module xxx. After some research, I learned that this error can be suppressed u ...

What is the best way to simulate global variables that are declared in a separate file?

dataConfiguration.js var userData = { URIs: { APIURI: "C" }, EncryptedToken: "D" }; configSetup.js config.set({ basePath: '', files:['dataConfiguration.js' ], ..... UserComponentDetails: .....some i ...

Why is the AngularJS 2 child @Component not being replaced in this scenario?

UPDATE: It seems that the issue lies in how I am structuring and serving the project rather than a coding problem. If I find a solution, I'll be sure to update this post. Thank you for your assistance. I'm currently developing an AngularJS 2 ap ...

Launching ngx-modal in Angular2 without the need for a button click

As a newcomer to Angular2, I am seeking guidance on how to trigger an alert Modal in the event of a failed login within my code. While most examples I have come across rely on a button click, I am wondering if it is possible to achieve this based on the st ...

Using TypeScript arrow function parentheses in the filter function

If I have an array of movie objects like this: const movies: Movie[] = [ movie1, movie2, movie3, movie4 ]; And if I want to remove a specific movie from the array, such as movie2, I can use the following code: movies = movies.filter( m => m !== ...

VIDEOJS ERROR: A peculiar mistake has occurred. TypeError: The property 'value' cannot be read since it is undefined in the context of

Recently, I came across a fascinating plugin called videojs-thumbnails for video.js, and I'm eager to incorporate it into my angular component. However, I keep encountering an error that says: VIDEOJS: ERROR: TypeError: Cannot read property 'val ...

What is the best way to bring in local modules within the browser environment using Playwright?

Let me illustrate what I am attempting to achieve: ../src/Foo/Bar.ts represents a local TypeScript file This particular file contains code that is designed to function within a browser environment (it utilizes WebSockets), and therefore needs to be execu ...

Tips for customizing standard data types in TypeScript

Currently facing a challenge where I need to update a global type. Specifically, I am looking to modify the signature of the Element.prototype.animate function to make it optional. This is the approach I attempted: declare global { interface Element { ...