TypeScript + React: Avoid setState on unmounted components












0














I know that a common pattern of avoiding calling .setState() on an unmounted component is by adding a private property such as _isMounted to keep track of it, as mentioned in a blog.



I've been using this method like this:



class Hello extends React.PureComponent{
_isMounted = false;

constructor(props) {
super(props);
this.state = {
// ...
};
}

componentDidMount() {
this._isMounted = true;
}

componentWillUnmount() {
this._isMounted = false;
}
// ...
}


Everything was fine until I started to use TypeScript. I tried to do this in the same way:



class Hello extends React.PureComponent<Props, State> {
private _isMounted: boolean;

constructor(props: Props) {
super(props);
this.state = {
// ...
};
}

componentDidMount() {
this._isMounted = true;
}

componentWillUnmount() {
this._isMounted = false;
}
}


But then it always throws a type error:



TypeError: Cannot set property _isMounted of #<Component> which has only a getter


For now, the only solution I know is to explicitly write a setter for it. But I don't really understand if this is the expected way to do it. Doesn't TypeScript generate getter and setter automatically?



Updated:

A codesandbox example: https://codesandbox.io/s/l59wnqy5zz










share|improve this question
























  • I think the problem must be in code you haven't shown. In the Hello class shown, _isMounted is clearly a data property, not an accessor property.
    – T.J. Crowder
    Nov 21 '18 at 14:57












  • The playground is happy with it (removed the React-isms, which shouldn't matter).
    – T.J. Crowder
    Nov 21 '18 at 14:58










  • I think _isMounted is a private property of React.Component. Rename it and it should work.
    – Stramski
    Nov 21 '18 at 15:13






  • 1




    or better yet, teardown any async stuff when unmount happens. eg if you have setTimeout / Interval, keep a reference and call clearTimeout. reactjs.org/blog/2015/12/16/ismounted-antipattern.html
    – Dimitar Christoff
    Nov 21 '18 at 15:17










  • @Stramski Yes it did work when I change the name! Thanks! But why didn't the private property we define here overwrite the one from React.Component?
    – catlicechew
    Nov 21 '18 at 15:24
















0














I know that a common pattern of avoiding calling .setState() on an unmounted component is by adding a private property such as _isMounted to keep track of it, as mentioned in a blog.



I've been using this method like this:



class Hello extends React.PureComponent{
_isMounted = false;

constructor(props) {
super(props);
this.state = {
// ...
};
}

componentDidMount() {
this._isMounted = true;
}

componentWillUnmount() {
this._isMounted = false;
}
// ...
}


Everything was fine until I started to use TypeScript. I tried to do this in the same way:



class Hello extends React.PureComponent<Props, State> {
private _isMounted: boolean;

constructor(props: Props) {
super(props);
this.state = {
// ...
};
}

componentDidMount() {
this._isMounted = true;
}

componentWillUnmount() {
this._isMounted = false;
}
}


But then it always throws a type error:



TypeError: Cannot set property _isMounted of #<Component> which has only a getter


For now, the only solution I know is to explicitly write a setter for it. But I don't really understand if this is the expected way to do it. Doesn't TypeScript generate getter and setter automatically?



Updated:

A codesandbox example: https://codesandbox.io/s/l59wnqy5zz










share|improve this question
























  • I think the problem must be in code you haven't shown. In the Hello class shown, _isMounted is clearly a data property, not an accessor property.
    – T.J. Crowder
    Nov 21 '18 at 14:57












  • The playground is happy with it (removed the React-isms, which shouldn't matter).
    – T.J. Crowder
    Nov 21 '18 at 14:58










  • I think _isMounted is a private property of React.Component. Rename it and it should work.
    – Stramski
    Nov 21 '18 at 15:13






  • 1




    or better yet, teardown any async stuff when unmount happens. eg if you have setTimeout / Interval, keep a reference and call clearTimeout. reactjs.org/blog/2015/12/16/ismounted-antipattern.html
    – Dimitar Christoff
    Nov 21 '18 at 15:17










  • @Stramski Yes it did work when I change the name! Thanks! But why didn't the private property we define here overwrite the one from React.Component?
    – catlicechew
    Nov 21 '18 at 15:24














0












0








0







I know that a common pattern of avoiding calling .setState() on an unmounted component is by adding a private property such as _isMounted to keep track of it, as mentioned in a blog.



I've been using this method like this:



class Hello extends React.PureComponent{
_isMounted = false;

constructor(props) {
super(props);
this.state = {
// ...
};
}

componentDidMount() {
this._isMounted = true;
}

componentWillUnmount() {
this._isMounted = false;
}
// ...
}


Everything was fine until I started to use TypeScript. I tried to do this in the same way:



class Hello extends React.PureComponent<Props, State> {
private _isMounted: boolean;

constructor(props: Props) {
super(props);
this.state = {
// ...
};
}

componentDidMount() {
this._isMounted = true;
}

componentWillUnmount() {
this._isMounted = false;
}
}


But then it always throws a type error:



TypeError: Cannot set property _isMounted of #<Component> which has only a getter


For now, the only solution I know is to explicitly write a setter for it. But I don't really understand if this is the expected way to do it. Doesn't TypeScript generate getter and setter automatically?



Updated:

A codesandbox example: https://codesandbox.io/s/l59wnqy5zz










share|improve this question















I know that a common pattern of avoiding calling .setState() on an unmounted component is by adding a private property such as _isMounted to keep track of it, as mentioned in a blog.



I've been using this method like this:



class Hello extends React.PureComponent{
_isMounted = false;

constructor(props) {
super(props);
this.state = {
// ...
};
}

componentDidMount() {
this._isMounted = true;
}

componentWillUnmount() {
this._isMounted = false;
}
// ...
}


Everything was fine until I started to use TypeScript. I tried to do this in the same way:



class Hello extends React.PureComponent<Props, State> {
private _isMounted: boolean;

constructor(props: Props) {
super(props);
this.state = {
// ...
};
}

componentDidMount() {
this._isMounted = true;
}

componentWillUnmount() {
this._isMounted = false;
}
}


But then it always throws a type error:



TypeError: Cannot set property _isMounted of #<Component> which has only a getter


For now, the only solution I know is to explicitly write a setter for it. But I don't really understand if this is the expected way to do it. Doesn't TypeScript generate getter and setter automatically?



Updated:

A codesandbox example: https://codesandbox.io/s/l59wnqy5zz







reactjs typescript






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 15:25







catlicechew

















asked Nov 21 '18 at 14:53









catlicechewcatlicechew

415




415












  • I think the problem must be in code you haven't shown. In the Hello class shown, _isMounted is clearly a data property, not an accessor property.
    – T.J. Crowder
    Nov 21 '18 at 14:57












  • The playground is happy with it (removed the React-isms, which shouldn't matter).
    – T.J. Crowder
    Nov 21 '18 at 14:58










  • I think _isMounted is a private property of React.Component. Rename it and it should work.
    – Stramski
    Nov 21 '18 at 15:13






  • 1




    or better yet, teardown any async stuff when unmount happens. eg if you have setTimeout / Interval, keep a reference and call clearTimeout. reactjs.org/blog/2015/12/16/ismounted-antipattern.html
    – Dimitar Christoff
    Nov 21 '18 at 15:17










  • @Stramski Yes it did work when I change the name! Thanks! But why didn't the private property we define here overwrite the one from React.Component?
    – catlicechew
    Nov 21 '18 at 15:24


















  • I think the problem must be in code you haven't shown. In the Hello class shown, _isMounted is clearly a data property, not an accessor property.
    – T.J. Crowder
    Nov 21 '18 at 14:57












  • The playground is happy with it (removed the React-isms, which shouldn't matter).
    – T.J. Crowder
    Nov 21 '18 at 14:58










  • I think _isMounted is a private property of React.Component. Rename it and it should work.
    – Stramski
    Nov 21 '18 at 15:13






  • 1




    or better yet, teardown any async stuff when unmount happens. eg if you have setTimeout / Interval, keep a reference and call clearTimeout. reactjs.org/blog/2015/12/16/ismounted-antipattern.html
    – Dimitar Christoff
    Nov 21 '18 at 15:17










  • @Stramski Yes it did work when I change the name! Thanks! But why didn't the private property we define here overwrite the one from React.Component?
    – catlicechew
    Nov 21 '18 at 15:24
















I think the problem must be in code you haven't shown. In the Hello class shown, _isMounted is clearly a data property, not an accessor property.
– T.J. Crowder
Nov 21 '18 at 14:57






I think the problem must be in code you haven't shown. In the Hello class shown, _isMounted is clearly a data property, not an accessor property.
– T.J. Crowder
Nov 21 '18 at 14:57














The playground is happy with it (removed the React-isms, which shouldn't matter).
– T.J. Crowder
Nov 21 '18 at 14:58




The playground is happy with it (removed the React-isms, which shouldn't matter).
– T.J. Crowder
Nov 21 '18 at 14:58












I think _isMounted is a private property of React.Component. Rename it and it should work.
– Stramski
Nov 21 '18 at 15:13




I think _isMounted is a private property of React.Component. Rename it and it should work.
– Stramski
Nov 21 '18 at 15:13




1




1




or better yet, teardown any async stuff when unmount happens. eg if you have setTimeout / Interval, keep a reference and call clearTimeout. reactjs.org/blog/2015/12/16/ismounted-antipattern.html
– Dimitar Christoff
Nov 21 '18 at 15:17




or better yet, teardown any async stuff when unmount happens. eg if you have setTimeout / Interval, keep a reference and call clearTimeout. reactjs.org/blog/2015/12/16/ismounted-antipattern.html
– Dimitar Christoff
Nov 21 '18 at 15:17












@Stramski Yes it did work when I change the name! Thanks! But why didn't the private property we define here overwrite the one from React.Component?
– catlicechew
Nov 21 '18 at 15:24




@Stramski Yes it did work when I change the name! Thanks! But why didn't the private property we define here overwrite the one from React.Component?
– catlicechew
Nov 21 '18 at 15:24












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53414723%2ftypescript-react-avoid-setstate-on-unmounted-components%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53414723%2ftypescript-react-avoid-setstate-on-unmounted-components%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Wiesbaden

Marschland

Dieringhausen