skip to Main Content

I have two components: legacy parent class component, let’s call it RowComponent, and child ModalComponent. State of those modal is located in parent component:

this.state = {
  modalIsOpen: false,
};

When I click on button it executes function which changes modalIsOpen state to true and modal is popped up. So far so good.

showRequestModal() {
  this.setState({ modalIsOpen: true });
}

Inside my child component I have isOpen state which is property that relies on modalIsOpen

<Modal
  width={600}
  destroyOnClose
  open={isOpen}
  onCancel={hideModalHandler}
/>

hideModalHandler is function that passed as property like this:

hideModalHandler={this.hideRequestModal}

That’s how my hideRequestModal looks like (it bind properly):

hideRequestModal() {
  console.log('Executing hideRequestModal');
  this.setState({ modalIsOpen: false }, () => {
    console.log('callback - modalIsOpen:', this.state.modalIsOpen);
  });
}

The real magic (or what I would say my lack of knowledge) starts here. When I try to close my modal from child component I can see text Executing hidRequestModal without changing the state (which I see from the callback). But the most bizarre thing is when I click ESC button on modal it closes (and state is updating). So my question is what the hell is going on and how to close modal on click also, not by clicking Escape key. So I suppose there is some conflicts in events or something like that. I consider rewriting parent component to be function component and maybe it will solve the issue but I don’t know. Appreciate any help

2

Answers


  1. Chosen as BEST ANSWER

    I have bumped into this issue: setState hook does't change state invoking from child

    Long story short fix is simple: just add event.stopPropagation() before updating state of modal visibility to false. Thanks everyone


  2. import { useState } from "react";
    
    const ChildComponent = ({ modalIsOpen, hideModalHandler }) => {
      const [isOpen, setIsOpen] = useState(modalIsOpen);
      return (
        <modal
          width={600}
          destroyOnClose
          open={isOpen}
          onCancel={hideModalHandler}
        />
      );
    };
    
    const RowComponent = () => {
      const [modalIsOpen, setModalIsOpen] = useState(false);
    
      const showRequestModal = () => {
        console.log("Executing showRequestModal");
        setModalIsOpen(true);
      };
    
      const hideRequestModal = () => {
        console.log("Executing hideRequestModal");
        setModalIsOpen(false);
      };
    
      return (
        <div>
          <button onClick={showRequestModal}>Click Me</button>
          <ChildComponent
            modalIsOpen={modalIsOpen}
            hideModalHandler={hideRequestModal}
          />
        </div>
      );
    };
    
    function App() {
      return <RowComponent />;
    }
    
    export default App;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search