最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - TypeScriptReactJSsetTimeout: 'this' implicitly has type 'any' because it does not h

programmeradmin2浏览0评论

In my NextJS/React typescript app I'm using a setTimeout.

There is a bug in React apps causing setTimeout's to get called instantly, which I then found a fix in this answer here: ReactJS: setTimeout() not working?

Below is my code, but I'm getting the following typescript error on the this on this.resetNotification

any 'this' implicitly has type 'any' because it does not have a type annotation.ts(2683) Board.tsx(158, 7): An outer value of 'this' is shadowed by this container.

@bind
resetNotification(): any {
  console.log('resetNotification...');
  this.setState({ notificationClass: 'spin-in-notification' });
  this.props.setNotification('', false);
}

@bind
private handleNotificationClick() {
  this.setState({ notificationClass: 'slide-out-bck-top' });

  setTimeout(
    function() {
      this.resetNotification();
    }
    .bind(this),
    500
  );
}

In my NextJS/React typescript app I'm using a setTimeout.

There is a bug in React apps causing setTimeout's to get called instantly, which I then found a fix in this answer here: ReactJS: setTimeout() not working?

Below is my code, but I'm getting the following typescript error on the this on this.resetNotification

any 'this' implicitly has type 'any' because it does not have a type annotation.ts(2683) Board.tsx(158, 7): An outer value of 'this' is shadowed by this container.

@bind
resetNotification(): any {
  console.log('resetNotification...');
  this.setState({ notificationClass: 'spin-in-notification' });
  this.props.setNotification('', false);
}

@bind
private handleNotificationClick() {
  this.setState({ notificationClass: 'slide-out-bck-top' });

  setTimeout(
    function() {
      this.resetNotification();
    }
    .bind(this),
    500
  );
}

Share Improve this question asked Mar 13, 2019 at 22:34 Leon GabanLeon Gaban 39k122 gold badges348 silver badges550 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 10

Do it with arrow function on setTimeout for heredate parents props

setTimeout(
  () => {
  this.resetNotification();
  }......

If you still want to use function () {} syntax, you can pass this as the first parameter to the function, along with a type annotation. Like this:

  setTimeout(
    function(this: Board) {
      this.resetNotification();
    }
    .bind(this),
    500
  );

I'm assuming since the file is called Board.tsx that your ponent is <Board>. If not, change the type annotation for this.

Just pass the function as a reference, no need to wrap it in an anonymous function or even bind it, which creates yet another function.

setTimeout(this.resetNotification, 500);

There is no bug in React calling setTimeout instantly, so if you were puzzled by it, consider this.

function doSomething() {/* */}

const a = doSomething() // immediately invokes and assigns a result
const b = doSomething   // stores a reference

// call later
const x = a() // error
const y = b() // invokes doSomething and assigns a result

And in your case, the "bug" you mention is basically the same thing.
When you register your setTimeout callback, you mistakenly immediately call it, where instead you should pass a reference to it.

function doSomething() {/* */}

// wrong
setTimeout(doSomething(), 500) // This is basically the same as writing the `a` from above
setTimeout(a, 500)             // like this. See the problem? a() cannot be called later.

To fix it, you have three options.

  1. pass a reference
setTimeout(this.resetNotification, 500)
  1. wrap in an anonymous arrow function which is transparent to this,
    meaning it captures the outer (parent) this.
    note that this wraps your function in another function every time you call this
setTimeout(() => this.resetNotification(), 500)
  1. wrap in a standard anonymous function, but since it es with it's own this, you must bind it to the this of the parent.
    note that this wraps your function in another function AND THEN binds it, which creates a third function every time
setTimeout(function(){this.resetNotification()}.bind(this), 500)

Enter setTimeout

setTimeout(callback, timeout?, param1?, param2?, ...)

It seems people don't realise that setTimeout and setInterval actually accept optional unlimited parameters. The reason is to make calling the callback simpler, so instead of this

setTimeout(
  function(){
    this.doSomething(true, "string", someVariable)
  }.bind(this),
  500
)

You can write this

setTimeout(this.doSomething, 500, true, "string", someVariable)

Isn't that beautiful and elegant?

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论