简体   繁体   English

React Native 中的 setTimeout

[英]setTimeout in React Native

I'm trying to load a splash screen for an iOS app built in React Native.我正在尝试为使用 React Native 构建的 iOS 应用程序加载启动画面。 I'm trying to accomplish this through class states and then a setTimeout function as follows:我正在尝试通过类状态和 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',
          }}/>
      );
    }
  }
}

The loading page works for a second, and then I guess when setTimeout tries to change the state to true, my program crashes: 'undefined is not an object (evaluating this.setState)'.加载页面工作了一秒钟,然后我猜想当 setTimeout 试图将状态更改为 true 时,我的程序崩溃了:“undefined is not an object (evaluating this.setState)”。 I've been going at this for a couple of hours, any ideas on how to fix it?我已经做了几个小时了,关于如何解决它有什么想法吗?

Classic javascript mistake.经典的 javascript 错误。

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

When setTimeout runs this.setState , this is no longer CowtanApp , but window .setTimeout运行this.setState时, this不再是CowtanApp ,而是window If you define the function with the => notation, es6 will auto-bind this .如果您使用=>符号定义函数,es6 将自动绑定this

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

Alternatively, you could use a let that = this;或者,您可以使用let that = this; at the top of your render , then switch your references to use the local variable.render的顶部,然后切换您的引用以使用局部变量。

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

If not working, use bind .如果不起作用,请使用bind

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

Write a new function for settimeout.为 settimeout 编写一个新函数。 Pls try this.请试试这个。

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',
      }}/>
  );
}
}
}
const getData = () => {
// some functionality
}

const that = this;
   setTimeout(() => {
   // write your functions    
   that.getData()
},6000);

Simple, Settimout function get triggered after 6000 milliseonds简单,Settimout 功能在 6000 毫秒后触发

Change this code:更改此代码:

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

to the following:到以下内容:

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

On ReactNative.53, the following works for me:在 ReactNative.53 上,以下对我有用:

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

'setTimeout' is the ReactNative library function. 'setTimeout' 是 ReactNative 库函数。
'this.timeoutCheck' is my variable to hold the time out object. 'this.timeoutCheck' 是我保存超时对象的变量。
'this.setTimePassed' is my function to invoke at the time out. 'this.setTimePassed' 是我在超时时调用的函数。

In case anyone wants it, you can also make the timer async and await it:如果有人需要,您还可以使计时器异步并等待它:

export const delay = (ms) => new Promise((res) => setTimeout(res, ms));

Usage:用法:

// do something
await delay(500); // wait 0.5 seconds
// do something else

You can bind this to your function by adding .bind(this) directly to the end of your function definition.您可以通过将.bind(this)直接添加到函数定义的末尾来将this绑定到您的函数。 You would rewrite your code block as:您可以将代码块重写为:

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

Never call setState inside render method永远不要在render方法中调用setState

You should never ever call setState inside the render method.永远不应该在render方法中调用setState Why?为什么? calling setState eventually fires the render method again.调用setState最终会再次触发render方法。 That means you are calling setState (mentioned in your render block) in a loop that would never end.这意味着你在一个永远不会结束的循环中调用 setState (在你的render块中提到)。 The correct way to do that is by using componentDidMount hook in React, like so:正确的做法是在 React 中使用componentDidMount钩子,如下所示:

class CowtanApp extends Component {
  state = {
     timePassed: false
  }

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

  render () {
    return this.state.timePassed ? (
        <NavigatorIOS
          style = {styles.container}
          initialRoute = {{
            component: LoginPage,
            title: 'Sign In',
        }}/>
    ) : <LoadingPage/>
  }
}

PS Use ternary operators for cleaner, shorter and readable code. PS 使用三元运算符以获得更简洁、更短和可读的代码。

I'm trying to load a splash screen for an iOS app built in React Native.我正在尝试为React Native内置的iOS应用加载启动画面。 I'm trying to accomplish this through class states and then a setTimeout function as follows:我试图通过类状态,然后通过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',
          }}/>
      );
    }
  }
}

The loading page works for a second, and then I guess when setTimeout tries to change the state to true, my program crashes: 'undefined is not an object (evaluating this.setState)'.加载页面会工作一秒钟,然后我猜想setTimeout尝试将状态更改为true时,我的程序崩溃了:“未定义不是对象(正在评估this.setState)”。 I've been going at this for a couple of hours, any ideas on how to fix it?我已经花了几个小时了,关于如何解决它的任何想法?

There looks to be an issue when the time of the phone/emulator is different to the one of the server (where react-native packager is running).当电话/模拟器的时间与服务器之一(运行本机打包程序的地方)不同时,似乎存在问题。 In my case there was a 1 minute difference between the time of the phone and the computer.在我的例子中,手机和电脑的时间相差 1 分钟。 After synchronizing them (didn't do anything fancy, the phone was set on manual time, and I just set it to use the network(sim) provided time), everything worked fine.同步它们后(没有做任何花哨的事情,手机设置为手动时间,我只是将其设置为使用网络(sim)提供的时间),一切正常。 This github issue helped me find the problem.这个github问题帮助我找到了问题。

import React, {Component} from 'react';
import {StyleSheet, View, Text} from 'react-native';

class App extends Component {
  componentDidMount() {
    setTimeout(() => {
      this.props.navigation.replace('LoginScreen');
    }, 2000);
  }

  render() {
    return (
      <View style={styles.MainView}>
        <Text>React Native</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  MainView: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;

Same as above, might help some people.同上,可能对某些人有帮助。

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM