React-modal: Question: Unmount component

Created on 21 Jun 2017  ·  18Comments  ·  Source: reactjs/react-modal

I have a problem with states inside react-modal. I have couple of components inside react-modal. After I close this modal and reopen again, states of internal components still the same (for instance, input values do not reset after modal toggling). Is there such a possibility to reset all state inside react-modal after close? I know it should be done inside componentWillUnmount but as far as I understood react-modal hides instead of unmounting.

My current solution is - do not render modal until open.

state = {
 isModalOpen: false
}

// somewhere in component
{ isModalOpen && <Modal isOpen={ isModalOpen }  /> }
help wanted question

All 18 comments

It is possible that maybe Modal.js#L113 and/or Modal.js#L129 are skipping some updates. (?)

@ajfuller any thoughts on this one?

@enheit is this with the latest 2.0.6 release? Just to make sure we're reproducing the issue correctly, could you create a minimal reproduction in a repo or on https://codesandbox.io/? Thanks!

@diasbruno it should only be preventing render if the state is different, so closing and reopening should trigger the renderPortal method.

We do have a blindspot in our tests for state changes of modals, so maybe there is something we're missing there 🤷‍♂️ (working on a PR that I should have out shortly)

@enheit I've created the following codesandbox: https://codesandbox.io/s/X4KQq22A

I'm not seeing the behavior as described with the latest published version. Are you rendering anything differently from my demo?

@ajfuller I use 1.7.1 version of react-modal. So, I need to update lib and review it again.
Does 2.0.6 release has incompatible changes with 1.7.1. According to versioning it has.

@enheit It should be compatible. The major version is just the modernization of the js syntax.

@diasbruno, @ajfuller thanks for reply. Here is my codesandbox example: https://codesandbox.io/s/oQjMMQjMX
It looks weird. I selected 1.7.1 version of react-modal and ControlledInput invokes componentWillUnmount.

This behavior can happen when removePortal is called or when the ModalPortal is ready to close which will return null or an empty div (and trigger unmount).

Anyway, I will check it tomorrow (will update to latest release) and provide you response.

@diasbruno, @ajfuller I have updated react-modal to 2.0.6 but state inside modal still the same. Is it depends on my libs? For example, I use redux state manager and redux-form. And this (redux-form) doesn't change after toggling window. Any idea?

You can check if redux-form don't clear the state after unmount. Since it stores the information on the redux state, it can recover the previous information. Probably, you will need to dispatch and action to clean the state.

@enheit I'm stuck with the same problem (using redux-form too). Did you find a solution finally?

@Neurostep unfortunately no :( If I will find solution it will be explained in this post ASAP.

@diasbruno & @ajfuller I've reproduced the same behavior as in my project. The input value still the same after open -> editing -> close -> open. On other hand, this state still the same because (I suppose) the modal doesn't know anything about child element state and don't know how to clean it. So, any idea? Should I look for workaround or there is a better solution?

Link: https://codesandbox.io/s/AOPrD0Y3

It only knows when to build the ModalPortal which contains the children, therefore the element is constructed and destructed when toggle the modal isOpen state.

In your example, you are accumulating state using handleInputChange and this is state is not internal to the modal, so you'll need to use onRequestClose to flush it.

onRequestClose = () => {
  // this is the opportunity to do a proper clean up.
  this.setState({ isOpen: !this.state.isOpen, inputValue: ''  <--- });
}

Examples:

<Modal ...>
  // state is inside the modal, so when modal is closed 
  // MyComponentWithState is destructed and so its state. 
  <MyComponentWithState /> 
</Modal>
<Modal ...>
  // state is outside the modal, so it does not manage it.
  <MyComponentReceivesState state={outerState} /> 
</Modal>

I finally found a solution how to fix this.
So, if you try to use your any elements right inside modal, this will not clear your values at all. But if you move your elements in separate component and just pass this component (which contains your elements) to the react-modal it will clear everything. If you didn't understand, take a look at example below:

// ModalComponent
<Modal ...>
   <form>
     <Field ... /> // It will not update your fields after close
   </form>
</Modal>
// ModalComponent
<Modal ...>
  <SomeForm />
</Modal>

// SomeForm
<form>
  <Field ... /> // This field will be reset after close
</form>

...or you can get more readable solution using this link: https://codesandbox.io/s/kRRp1ZQwY

Ah, got it. Sorry for the bad answer.

In redux-form, the default behavior is to destroy when unmount. redux-form@master:/src/createReduxForm.js#L89.

One probable reason is because when toggle isOpen attribute on Modal, it's never calls to unmount on ModalPortal, therefore unmount on the form is not called. See src/components/Modal.js#L129

There is room for further inspection on this issue.

I'm going to open a new discussion about this issue.

Thank you, @enheit.

Was this page helpful?
0 / 5 - 0 ratings