ReactJS and UIkit 3.6.5: click event isn't fired inside modal window

Viewed 665

I develop an app on ReactJS and trying to configure UIkit modal window. The problem is that the click handler on the button("Save") does not work, the click event is basically not listened inside the modal window. I put the button out the modal window - click event works(the message appears in the console). Is this a bug or am I doing something wrong? Thanks for attention!

return(
    <>
        <button
         className="uk-button uk-button-primary uk-modal-close"
         type="button"
         onClick={() => console.log("Click")}>Save</button> {/* It works */}
         
        <button className="uk-button uk-button-primary" uk-toggle="target: #modal-save">Publish</button>           
        
        <div id="modal-save" uk-modal="true">
            <div className="uk-modal-dialog uk-modal-body">                    
                <p>Save changes?</p>
                <p className="uk-text-right">                                               
                    <button className="uk-button uk-button-default uk-modal-close" type="button">Cancel</button>
                    <button
                     className="uk-button uk-button-primary uk-modal-close"
                     type="button"
                     onClick={() => console.log("Click")}>Save</button> {/* Doesn't work */}
                </p>
            </div>
        </div>
        
        
    </>
    
);
1 Answers

This problem is caused by changes in event delegation(React 17) - https://reactjs.org/blog/2020/10/20/react-v17.html#changes-to-event-delegation

I solved this with Portals(https://reactjs.org/docs/portals.html) i.e.

const ModalPortal = props => {
  const modalRoot = document.createElement('div');
  modalRoot.setAttribute('uk-modal', 'bg-close: false');
  modalRoot.id = 'modal-save';

  useEffect(() => {
    document.body.appendChild(modalRoot);
    return () => {
      document.body.removeChild(modalRoot);
    }
  });

  return ReactDOM.createPortal(props.children, modalRoot);
} 

export default ModalPortal;

Then you should wrap modal content in parent element

<ModalPortal>
  // modal body
  <span onClick={() => console.log('test')}>Test</span>
</ModalPortal>
Related