web-dev-qa-db-ja.com

React NativeのsetTimeout

React Nativeで構築されたiOSアプリのスプラッシュスクリーンをロードしようとしています。次のようにクラス状態とsetTimeout関数を介してこれを達成しようとしています。

class CowtanApp extends Component {
  constructor(props){
    super(props);
    this.state = {
      timePassed: false
    };
  }

  render() {
    setTimeout(function(){this.setState({timePassed: true})}, 1000);
    if (!this.state.timePassed){
      return <LoadingPage/>;
    }else{
      return (
        <NavigatorIOS
          style = {styles.container}
          initialRoute = {{
            component: LoginPage,
            title: 'Sign In',
          }}/>
      );
    }
  }
}

ロードページが1秒間機能し、setTimeoutが状態をtrueに変更しようとすると、プログラムがクラッシュします。「undefinedはオブジェクトではありません(this.setStateを評価します)」。私は数時間これに行ってきましたが、それを修正する方法についてのアイデアはありますか?

52
Phil

古典的なJavaScriptの間違い。

setTimeout(function(){this.setState({timePassed: true})}, 1000)

setTimeoutthis.setStateを実行すると、thisCowtanAppではなく、windowになります。 =>表記で関数を定義すると、es6はthisを自動バインドします。

setTimeout(() => {this.setState({timePassed: true})}, 1000)

または、renderの上部でlet that = this;を使用し、ローカル変数を使用するように参照を切り替えることもできます。

render() {
  let that = this;
  setTimeout(function(){that.setState({timePassed: true})}, 1000);
109
user1221780

Settimeoutの新しい関数を作成します。これを試してください。

class CowtanApp extends Component {
  constructor(props){
  super(props);
  this.state = {
  timePassed: false
  };
}

componentDidMount() {
  this.setTimeout( () => {
     this.setTimePassed();
  },1000);
}

setTimePassed() {
   this.setState({timePassed: true});
}


render() {

if (!this.state.timePassed){
  return <LoadingPage/>;
}else{
  return (
    <NavigatorIOS
      style = {styles.container}
      initialRoute = {{
        component: LoginPage,
        title: 'Sign In',
      }}/>
  );
}
}
}
13
Phyo

ReactNative .53では、次のように機能します。

 this.timeoutCheck = setTimeout(() => {
   this.setTimePassed();
   }, 400);

'setTimeout'はReactNativeライブラリ関数です。
'this.timeoutCheck'は、タイムアウトオブジェクトを保持する変数です。
'this.setTimePassed'は、タイムアウト時に呼び出す私の関数です。

5
david m lee

.bind(this)を関数定義の最後に直接追加することで、thisを関数にバインドできます。コードブロックを次のように書き換えます。

setTimeout(function () {
  this.setState({ timePassed: true });
}.bind(this), 1000);
3
Scott Carpenter

このコードを変更します。

setTimeout(function(){this.setState({timePassed: true})}, 1000);

以下に:

setTimeout(()=>{this.setState({timePassed: true})}, 1000); 
1
wandhi Zakari

上記と同じ、一部の人々を助けるかもしれません。

setTimeout(() => {
  if (pushToken!=null && deviceId!=null) {
    console.log("pushToken & OS ");
    this.setState({ pushToken: pushToken});
    this.setState({ deviceId: deviceId });
    console.log("pushToken & OS "+pushToken+"\n"+deviceId);
  }
}, 1000);
0
Dunken_sai