0

Before you read, I must say that I am aware that this is a common question here.

I have a modal that based on a prop that isOpen, will decide if the modal will be visible or not, but i need to keep track of the state of that modal so i can hide it after i am done using it, somehow i made it work in this form as it is now, but it shows me the warning Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s ... I tried to search what is causing this problem and according to this it should be fixed, but I am still having that warning. I am new to react native and I don't fully understand what is happening. I would greatly appreciate if somebody can help me understand what the problem is and how to solve it.

export default class Update extends React.Component {
    _isMounted = false;
    constructor(props) {
        super(props);
        this.state = {
            modalOpen: false,
            name: this.props.name,
        };
    }
    componentDidUpdate(prevProps) {
        this._isMounted = true;
        if (this._isMounted) {
            if (this.props.isOpen !== prevProps.isOpen) {
                this.setState({ modalOpen: true })
            }
        }
    }
    componentWillUnmount() {
        this._isMounted = false;
    }

    update(updateObj, file) {
        const { navigate } = this.props;
        remove(file);
        addFile(updateObj);
        this.setState({ modalOpen: false });
        navigate('Main');
    }
    render() {
        const { name, modalOpen } = this.state;
        const { closeModal, file } = this.props;
        return (
            <Modal
                isOpen={modalOpen}
                closeModal={closeModal}>
                <TextInput
                    style={{ height: 60 }}
                    onChangeText={(name) => this.setState({ name })}
                    value={this.state.name}
                />
                <Button
                    title="Update File"
                    onPress={
                        () => this.update({
                            name: this.state.name,
                        }, file)
                    }
                />
            </Modal>
        );
    }
}
Sachihiro
  • 1,597
  • 2
  • 20
  • 46
  • When are you closing the modal? – Konstantin Dec 04 '19 at 16:06
  • Usually this happens when your modal is updating it's own state after the modal has been unmounted (closed). Try and follow the flow of when it is being opened and closed and keep track of everything that is happening in the background. Especially if the modal is being closed by a parent component. – mlisonek Dec 04 '19 at 16:08
  • I will edit the question to show the function that close the modal. – Sachihiro Dec 04 '19 at 16:09
  • Can you try to add a condition to your componentDidUpdate, which is ```this.props.isOpen !== prevProps.isOpen && this.props.isOpen```, just trying to trigger it only when ```this.props.isOpen``` is ```true``` – Konstantin Dec 04 '19 at 16:17
  • @Konstantin i tried that, but still the same. Now i posted the entire component and might be easier to spot. – Sachihiro Dec 04 '19 at 16:23

2 Answers2

0

you must perform setState's after the component is mounted, which is after componentDidMount(), and while render(), componentDidUpdate() and componentWillUnmount() happen

Matteus Barbosa
  • 2,409
  • 20
  • 21
0

One of the problems of this code is the way you have implemented this._isMounted.

In your case, anytime the component updates, _isMounted variable is going to be set to true, therefore the condition is going to be triggered and the state is going to be updated, so it's not really saving you from anything.

Could you try doing something like:

componentDidUpdate(prevProps) {
        if (this.props.isOpen) this._isMounted = true;
        if (this._isMounted) {
            if (this.props.isOpen !== prevProps.isOpen) {
                this.setState({ modalOpen: true })
            }
        }
    }

UPD (if someone stumbles upon this):

The original problem was in the update function, line this.setState({modalOpen: false}), so the OP decided to stop using the state in the component to display the Modal and instead use this.props.isOpen from the parent component and set this.props.isOpen to false once the function update has been triggered (all in the parent component). And the warning has gone away!

Konstantin
  • 1,390
  • 6
  • 18
  • The warning is still there. Does it indicate that the problem might be elsewhere? – Sachihiro Dec 04 '19 at 16:39
  • You can try passing the props value to the Modal directly, without setting the state, and commenting out the lines which set the state of modal. If the warning goes away, then it's the source of the problems, if not let's search elsewhere – Konstantin Dec 04 '19 at 16:41
  • it was initially like that, i passed the props value directly, but i need a way to close the modal when i press update, that is what lead me to have this trouble. – Sachihiro Dec 04 '19 at 16:46
  • If you comment out the line with ```this.setState({modalOpen: false})``` in your function, does the warning go away (I know that the modal then stays open) – Konstantin Dec 04 '19 at 16:52
  • The error goes, and I solve the problem by updating the state in `Main` view. Edit your answer so I will mark it as solution :) thanks man. – Sachihiro Dec 04 '19 at 16:56
  • Edited to incorporate what you've done in case someone stumbles upon this. Glad it finally worked out! :) – Konstantin Dec 04 '19 at 17:05