'react-router-dom Link on click close bootstrap modal window

I need to close the modal window by clicking on the link. My modal window:

export const ModalWrapper = (props) => {
  const { children, title, modalName } = props;
  return (
    <div
      className="modal fade"
      id={`modal-${modalName}`}
      tabIndex="-1"
      role="dialog"
      aria-labelledby="modal-label"
      aria-hidden="true"
      style={{ display: 'none' }}
    >
      <div className="modal-dialog modal">
        <div className="modal-content" style={{ overflow: 'hidden' }}>
          <div className="modal-header">
            { title }
            <button type="button" className="close" data-dismiss="modal" aria-hidden="true">×</button>

          </div>
          <div className="modal-body" style={{ maxHeight: '435', overflowY: 'auto' }}>
            <ul className="list-unstyled todo-list">
              {children}
            </ul>
          </div>
        </div>
      </div>
    </div>
  );
};

How can I close window with react-router-dom Link?

It close window without redirect:

<Link to="/registration" data-dismiss="modal" className="btn btn-default">Registration</Link>

It redirects but the window does not close:

<Link to="/registration" className="btn btn-default">Registration</Link>

Thank you!



Solution 1:[1]

To achieve your goal you can either:

You can read more about React Bootstrap library at their website.

If you want to avoid extra dependencies, you can use React's ref functionality: https://reactjs.org/docs/refs-and-the-dom.html and use it to manipulate the dom (e.g. hide the dialog on Link click or any other action). In this case simply attach ref callback function to the dialog dom element:

<div className="modal" ref={(input) => {this.input = input}}>
...

In this case you can access dom's className and remove the show class from it. Be aware that you will also have to remove show from the fade container (dimmed background generated by Bootstrap).

My overall suggestion is to use utility function that will hide current modal and fade. Smth like:

const hideActiveModal = () => {
  const modal = document.getElementsByClassName('modal show')[0];
  const fade = document.getElementsByClassName('modal-backdrop show')[0];
  modal.className = modal.className.replace('show', '');
  fade.className = fade.className.replace('show', '');
};

Conclusion: you can't hide Bootstrap using clear React at moment. Either use React-Bootstrap or use util function (like the one I have provided).

Solution 2:[2]

As an update, this can now be solved by monitoring the location of the router in React Router V6 and combining with useRef() to set the initial location:

    const location = useLocation();
    const [showModal, setShowModal] = useState(true);

    const initialPage = useRef(location.pathname);

    useEffect(() => {
        if (location.pathname !== initialPage.current) {
            setShowModal(false);
        }
    }, [location]);

I'm using React Bootstrap, but for your current implementation, you could update the relevant classNames:

className={`modal ${showModal ? 'show', ''}`}

You'd also need to update the close button:

   onClick={() => {
      setShowModal(false);
   }}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 0leg
Solution 2