web-dev-qa-db-ja.com

reactjsのタイムアウトを停止しますか?

Reactjsでタイムアウトを殺す/(取り除く)できる方法はありますか?

setTimeout(function() {
//do something
}.bind(this), 3000);

何らかのクリックまたはアクションが発生したときに、タイムアウトを完全に停止および終了できるようにしたいと考えています。これを行う方法はありますか?ありがとう。

15
BlueElixir

ミックスインを使用する必要があります。

// file: mixins/settimeout.js:

var SetTimeoutMixin = {
    componentWillMount: function() {
        this.timeouts = [];
    },
    setTimeout: function() {
        this.timeouts.Push(setTimeout.apply(null, arguments));
    },

    clearTimeouts: function() {
        this.timeouts.forEach(clearTimeout);
    },

    componentWillUnmount: function() {
        this.clearTimeouts();
    }
};

export default SetTimeoutMixin;

...そしてあなたのコンポーネントで:

// sampleComponent.js:
import SetTimeoutMixin from 'mixins/settimeout'; 

var SampleComponent = React.createClass({

    //mixins:
    mixins: [SetTimeoutMixin],

    // sample usage
    componentWillReceiveProps: function(newProps) {
        if (newProps.myValue != this.props.myValue) {
            this.clearTimeouts();
            this.setTimeout(function(){ console.log('do something'); }, 2000);
        }
    },
}

export default SampleComponent;

詳細: https://facebook.github.io/react/docs/reusable-components.html

10
Tomasz Szuba

これがコンポーネント内で発生していると仮定すると、タイムアウトIDを保存して、後でキャンセルできるようにします。それ以外の場合は、外部ストアオブジェクトのように、後でアクセスできる別の場所にIDを保存する必要があります。

_this.timeout = setTimeout(function() {
  // Do something
  this.timeout = null
}.bind(this), 3000)

// ...elsewhere...

if (this.timeout) {
  clearTimeout(this.timeout)
  this.timeout = null
}
_

また、componentWillUnmount()でも保留中のタイムアウトがキャンセルされることを確認する必要があります。

_componentWillUnmount: function() {
  if (this.timeout) {
    clearTimeout(this.timeout)
  }
}
_

タイムアウトが保留中かどうかに依存するUIがある場合は、代わりに適切なコンポーネントの状態でIDを保存する必要があります。

21
Jonny Buchanan

Reactミックスインは非推奨になったため、別のコンポーネントをラップして受け入れられた回答に記載されている機能と同じ機能を提供する高次コンポーネントの例を次に示します。そして、小道具を介してこれを管理するためのAPIを子コンポーネントに提供します。

これは、ES6クラスと コンポーネント構成 を使用します。これは、2017年にmixinを置き換える推奨方法です。

Timeout.jsx

import React, { Component } from 'react';

const Timeout = Composition => class _Timeout extends Component {
    constructor(props) {
      super(props);
    }

    componentWillMount () {
      this.timeouts = [];
    }

    setTimeout () {
      this.timeouts.Push(setTimeout.apply(null, arguments));
    }

    clearTimeouts () {
      this.timeouts.forEach(clearTimeout);
    }

    componentWillUnmount () {
      this.clearTimeouts();
    }

    render () {
      const { timeouts, setTimeout, clearTimeouts } = this;

      return <Composition 
        timeouts={timeouts} 
        setTimeout={setTimeout} 
        clearTimeouts={clearTimeouts} 
        { ...this.props } />
    }
}

export default Timeout;

MyComponent.jsx

import React, { Component } from 'react';
import Timeout from './Timeout';    

class MyComponent extends Component {
  constructor(props) {
    super(props)
  }

  componentDidMount () {
    // You can access methods of Timeout as they
    // were passed down as props.
    this.props.setTimeout(() => {
      console.log("Hey! I'm timing out!")
    }, 1000)
  }

  render () {
    return <span>Hello, world!</span>
  }
}

// Pass your component to Timeout to create the magic.
export default Timeout(MyComponent);
10
jmgem

Javascriptのみを使用して、reactアプリでsetTimeoutを停止しました。

(私の使用例は、キーストロークなしの3秒の明確な後のみ自動保存することでした)

timeout;

handleUpdate(input:any) {
    this.setState({ title: input.value }, () => {

        clearTimeout(this.timeout);
        this.timeout = setTimeout(() => this.saveChanges(), 3000);

    });
}
1
Ben Cochrane