ReactJS:setTimeout()が機能していませんか?


101

このコードを念頭に置いて:

var Component = React.createClass({

    getInitialState: function () {
        return {position: 0};    
    },

    componentDidMount: function () {
        setTimeout(this.setState({position: 1}), 3000);
    },

    render: function () {
         return (
            <div className="component">
                {this.state.position}
            </div>
         ); 
    }

});

ReactDOM.render(
    <Component />,
    document.getElementById('main')
);

状態は3秒後にのみ変化するはずではありませんか?それはすぐに変わります。

ここでの主な目標は、3秒ごとに(を使用してsetInterval())状態を変更することですが、機能しなかったため、も機能しませんでしたsetTimeout()。これに光はありますか?ありがとう!


2
あなたが持っている場合はfoo(bar())、その後barされ、最初に実行し、その戻り値が渡されますfoo
Felix Kling 2016年

@FelixKlingは正しいようですが、適切ではありません。のでfoo()、ここでは正確に実行するためにbar必要なタイムアウト後。または、私は完全に間違っていてすぐに実行され、目的の時間の後にのみ値を返しますか?
jbarradas

3
「ここでのfoo()は、目的のタイムアウト後にbarを実行するためのものです。」そうです、それを渡さなければbarならず、それを呼び出さずにその戻り値を渡さなければなりません。foo(bar())fooをしているのかに応じて、の動作が変わることを期待しましたか?それは本当に奇妙なことです。
Felix Kling 2016年

回答:


241

行う

setTimeout(
    function() {
        this.setState({ position: 1 });
    }
    .bind(this),
    3000
);

それ以外の場合は、setStateto の結果を渡しますsetTimeout

ES6の矢印関数を使用して、thisキーワードの使用を回避することもできます。

setTimeout(
  () => this.setState({ position: 1 }), 
  3000
);

1
ええ、理にかなっていて、それは機能しています。しかし、function()は関数ではありませんか?では、なぜそれをバインドする必要があるのでしょうか。私はすでに試しました、そしてそれは本当に必要です、私はただ理由を知りたかったです。よろしくお願いします:)
jbarradas

結果がsetTimeoutに渡されると言っている理由がわかりません。どうしてこれが機能しないのですか。その場合の動作は何ですか?
PositiveGuy

16
ES6の矢印関数の使用を好む方のために: setTimeout(() => {this.setState({ position: 1 })}, 3000)@PositiveGuyは、この質問が投稿されてから自分でこれを調べたかどうかはわかりませんが、知らなかった場合:ダニエルの元の例では.bind(this)thisコンテキストを制限する必要がありますsetState-それ以外の場合、thisそれが呼び出されたコンテキストを自動的に参照します(この場合、匿名functionはに渡されますsetTimeout)。ただし、ES6アロー関数はレキシカルにスコープが設定さthisれています- それらは呼び出されたコンテキストに制限されます。
Zac Collier

1
動作しません... setTimeout(()=> {if(!this.props.logoIsLoading &&!this.props.isLoading){console.log( 'Will we発生?'); this.setState({.. .this.state、shouldUpdate:false、itemToUpdate:null、modalIsOpen:false、modalTitle: 'Add New Organization'});}}、100); クラスシンタックスシュガークラスOrganizationsのコンテキストでは、Componentsを拡張します{console.logはconsole.logを取得しません。その前と後のすべてが記録されます。
juslintek 2017年

@juslintekの定義は機能しません。必要に応じて、新しい質問をしてください。
ダニエルA.ホワイト

150
setTimeout(() => {
  this.setState({ position: 1 });
}, 3000);

ES6の矢印関数はのコンテキストを変更しないため、上記も機能しますthis


3
ES6構文は、Reactのベストプラクティスの受け入れられた回答である必要があります。どちらも機能しますが、これはよりエレガントで処理しthisます。
mccambridge 2017

24

タイムアウトを作成するときはいつでも、それがまだ発火していない場合は、componentWillUnmountでタイムアウトをクリアする必要があります。

      let myVar;
         const Component = React.createClass({

            getInitialState: function () {
                return {position: 0};    
            },

            componentDidMount: function () {
                 myVar = setTimeout(()=> this.setState({position: 1}), 3000)
            },

            componentWillUnmount: () => {
              clearTimeout(myVar);
             };
            render: function () {
                 return (
                    <div className="component">
                        {this.state.position}
                    </div>
                 ); 
            }

        });

ReactDOM.render(
    <Component />,
    document.getElementById('main')
);

11

私はこれが少し古いことを知っていますが、コンポーネントがアンマウントするときにReactが間隔を空けることを推奨することに注意することが重要です:https : //reactjs.org/docs/state-and-lifecycle.html

だから私はこの議論にこの回答を追加したいです:

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
  componentWillUnmount() {
    clearInterval(this.timerID);
  }

8

setState括弧があるため、すぐに呼び出されます!それを無名関数でラップしてから呼び出します。

setTimeout(function() {
    this.setState({position: 1})
}.bind(this), 3000);

6

誰がsetTimeoutを呼び出したかはわかりませんでした

ここでは、追加の関数を呼び出さずにタイムアウトを呼び出す方法について説明します。

1.追加機能を作成せずにこれを行うことができます。

setTimeout(this.setState.bind(this, {position:1}), 3000);

function.prototype.bind()を使用します

setTimeoutは関数の場所を取得し、コンテキスト内に保持します。

2.さらに少ないコードを書くことによって同じことを行う別の方法。

setTimeout(this.setState, 3000, {position:1});

おそらくある時点で同じバインド方法を使用します

setTimeoutは関数の場所のみを取得し、関数はすでにコンテキストを持っていますか?とにかく、それはうまくいきます!

注:これらは、jsで使用するすべての関数で機能します。


5

コードスコープ(thiswindow、reactコンポーネントではなくオブジェクトになりますsetTimeout(this.setState({position: 1}), 3000)。そのため、この方法でクラッシュします。

それはReactではなくjavascriptから来ています、それはjsの閉鎖です


したがって、現在の反応コンポーネントのスコープをバインドするには、次のようにします。

setTimeout(function(){this.setState({position: 1})}.bind(this), 3000);

または、ブラウザがes6をサポートしているか、projsがes6をes5にコンパイルすることをサポートしている場合は、矢印関数も試してください。

setTimeout(()=>this.setState({position: 1}), 3000);

3

「setTimeout」関数内のスコープにアクセスする方法は3つあります

最初、

const self = this
setTimeout(function() {
  self.setState({position:1})
}, 3000)

2つ目は、ES6の矢印関数を使用することです。矢印関数にそれ自体のスコープがありませんでした(これ)

setTimeout(()=> {
   this.setState({position:1})
}, 3000)

3つ目は、スコープを関数内にバインドすることです。

setTimeout(function(){
   this.setState({position:1})
}.bind(this), 3000)

1

構文宣言エラーが発生しました。適切なsetTimeout宣言を使用してください

message:() => { 
  setTimeout(() => {this.setState({opened:false})},3000); 
  return 'Thanks for your time, have a nice day 😊! 
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.