TypeScript + React: Avoid setState on unmounted components
up vote
0
down vote
favorite
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
|
show 1 more comment
up vote
0
down vote
favorite
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
I think the problem must be in code you haven't shown. In theHelloclass shown,_isMountedis clearly a data property, not an accessor property.
– T.J. Crowder
Nov 21 at 14:57
The playground is happy with it (removed the React-isms, which shouldn't matter).
– T.J. Crowder
Nov 21 at 14:58
I think _isMounted is a private property of React.Component. Rename it and it should work.
– Stramski
Nov 21 at 15:13
1
or better yet, teardown any async stuff when unmount happens. eg if you havesetTimeout/Interval, keep a reference and callclearTimeout. reactjs.org/blog/2015/12/16/ismounted-antipattern.html
– Dimitar Christoff
Nov 21 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 at 15:24
|
show 1 more comment
up vote
0
down vote
favorite
up vote
0
down vote
favorite
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
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
reactjs typescript
edited Nov 21 at 15:25
asked Nov 21 at 14:53
catlicechew
415
415
I think the problem must be in code you haven't shown. In theHelloclass shown,_isMountedis clearly a data property, not an accessor property.
– T.J. Crowder
Nov 21 at 14:57
The playground is happy with it (removed the React-isms, which shouldn't matter).
– T.J. Crowder
Nov 21 at 14:58
I think _isMounted is a private property of React.Component. Rename it and it should work.
– Stramski
Nov 21 at 15:13
1
or better yet, teardown any async stuff when unmount happens. eg if you havesetTimeout/Interval, keep a reference and callclearTimeout. reactjs.org/blog/2015/12/16/ismounted-antipattern.html
– Dimitar Christoff
Nov 21 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 at 15:24
|
show 1 more comment
I think the problem must be in code you haven't shown. In theHelloclass shown,_isMountedis clearly a data property, not an accessor property.
– T.J. Crowder
Nov 21 at 14:57
The playground is happy with it (removed the React-isms, which shouldn't matter).
– T.J. Crowder
Nov 21 at 14:58
I think _isMounted is a private property of React.Component. Rename it and it should work.
– Stramski
Nov 21 at 15:13
1
or better yet, teardown any async stuff when unmount happens. eg if you havesetTimeout/Interval, keep a reference and callclearTimeout. reactjs.org/blog/2015/12/16/ismounted-antipattern.html
– Dimitar Christoff
Nov 21 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 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 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 at 14:57
The playground is happy with it (removed the React-isms, which shouldn't matter).
– T.J. Crowder
Nov 21 at 14:58
The playground is happy with it (removed the React-isms, which shouldn't matter).
– T.J. Crowder
Nov 21 at 14:58
I think _isMounted is a private property of React.Component. Rename it and it should work.
– Stramski
Nov 21 at 15:13
I think _isMounted is a private property of React.Component. Rename it and it should work.
– Stramski
Nov 21 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 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 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 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 at 15:24
|
show 1 more comment
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
I think the problem must be in code you haven't shown. In the
Helloclass shown,_isMountedis clearly a data property, not an accessor property.– T.J. Crowder
Nov 21 at 14:57
The playground is happy with it (removed the React-isms, which shouldn't matter).
– T.J. Crowder
Nov 21 at 14:58
I think _isMounted is a private property of React.Component. Rename it and it should work.
– Stramski
Nov 21 at 15:13
1
or better yet, teardown any async stuff when unmount happens. eg if you have
setTimeout/Interval, keep a reference and callclearTimeout. reactjs.org/blog/2015/12/16/ismounted-antipattern.html– Dimitar Christoff
Nov 21 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 at 15:24