React Native - 无法清除超时

Posted

技术标签:

【中文标题】React Native - 无法清除超时【英文标题】:React Native - Can't ClearTimeout 【发布时间】:2019-09-29 11:10:28 【问题描述】:

我想为用户在 web 视图中从一个页面导航到另一个页面设置超时,这样如果加载页面需要几秒钟以上的时间来加载,我会显示一个错误视图,否则我会清除超时和用户继续当前页面。

我把定时器设置为全局变量,但是不知道为什么没有清零,一直在执行函数errorView()

这是代码:

import React from 'react';
import  StyleSheet, Text, View, TextInput, TouchableOpacity, BackHandler  from 'react-native';
import WebView, Platform, ActivityIndicator from 'react-native';
import Geolocation from 'react-native/Libraries/Geolocation/Geolocation.js';

class App extends React.Component 

    constructor() 
        super();
        this.state = 
            visible: true,
            error: false,
            uri: 'http://127.0.0.1/',
            canGoBack: false,
            ref: null,
        ;
        global.timer = null;
    

    showSpinner() 
        this.setState( visible: true );
    

    hideSpinner() 
        this.setState( visible: false );
    

    errorView() 
        this.setState( error: true );
        this.hideSpinner();
    

    reloadView() 
        this.setState( visible: true );
        this.setState( error: false );
        this.state.ref.reload();
    


    onandroidBackPress = () => 
        if (this.state.canGoBack && this.state.ref) 
            this.state.ref.goBack();
            return true;
        
        return false;
    

    componentWillMount() 
        if (Platform.OS === 'android') 
            BackHandler.addEventListener('hardwareBackPress', this.onAndroidBackPress);
        
        timer = null;
    

    componentWillUnmount() 
        if (Platform.OS === 'android') 
            BackHandler.removeEventListener('hardwareBackPress');
        
    

    render() 
        return (

            <View
                style=this.state.visible === true ? styles.stylOld : styles.styleNew>

                this.state.error === true ? (
                    <View style=styles.stylOld>
                        <Text style=styles.failedToLoad>Failed To Load Page</Text>
                        <TouchableOpacity style=styles.reloadBtn onPress=() => this.reloadView()><Text>Reload</Text></TouchableOpacity>
                    </View>
                ) : null

                this.state.visible ? (
                    <View>
                        <Text style=styles.loadingText>Dr. Mosul</Text>
                        <ActivityIndicator
                            color="white"
                            size="large"
                            style=styles.ActivityIndicatorStyle
                        />
                    </View>
                ) : null

                <WebView
                ref=(webView) =>  this.state.ref = webView; 
                source=uri: this.state.uri
                style=styles.WebViewStyle
                javascriptEnabled=true
                cacheEnabled=true
                scalesPageToFit=false
                geolocationEnabled=true
                onLoadStart=() => 
                    this.showSpinner();
                    global.timer = setTimeout(() => this.errorView();, 5000);
                
                onLoad=() => 
                    this.hideSpinner();
                    if (global.timer !== undefined && global.timer !== null) 
                        clearTimeout(global.timer);
                    
                
                onError=() => 
                    this.errorView();
                    if (global.timer !== undefined && global.timer !== null) 
                        clearTimeout(global.timer);
                    
                
                onNavigationStateChange=(navState) => 
                    this.state.canGoBack = navState.canGoBack;
                
                
            />
            </View>


        )
    



const styles = StyleSheet.create(
    stylOld: 
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        paddingTop: '50%',
        backgroundColor: 'rgb(10, 150, 255)'
    ,
    styleNew: 
        flex: 1,
    ,
    WebViewStyle: 
        justifyContent: 'center',
        alignItems: 'center',
        flex: 1,
        marginTop: 0,
    ,
    loadingText: 
        justifyContent: 'center',
        alignItems: 'center',
        fontSize: 50,
        color: 'white'
    ,
    ActivityIndicatorStyle: 
        justifyContent: 'center',
        alignItems: 'center',
        position: 'relative',
    ,
    failedToLoad: 
        fontSize: 50,
        color: 'white'
    ,
    reloadBtn: 
        backgroundColor: 'red',
    
);



export default App```

【问题讨论】:

请不要添加关于您被困多长时间的陈述。这是一种恳求形式,可能不会让志愿读者感到兴奋,而且我们无论如何都会删减闲聊/对话材料。想想问题应该如何措辞,以便三年后它们变得可读和有用,当你不再拘泥于它们时 - 答案是简洁的技术写作是做到这一点的方法。 【参考方案1】:

我没有看到“全局”的定义,不确定这是 react 本身的一部分还是包含的库之一。我希望这里有一个 ReferenceError,但由于它是 react-native 而不是 reactjs,因此在这种情况下可能会自动恢复错误。我希望它会崩溃。

因此,您可以在类之外声明 timer 变量以查看它是否确实是一个范围问题,或者甚至只是使用 this.timer 或其他东西并将其设为类字段。

【讨论】:

以上是关于React Native - 无法清除超时的主要内容,如果未能解决你的问题,请参考以下文章

SyntaxError - node_modules/react-native/Libraries/polyfills/error-guard.js:缺少分号。 (14:4) 在 react nati

iOS 无法在 react-native-firebase 中接收通知

Android Emulator 无法连接到 React-Native 远程调试器 - 连接时超时

视频的背景音频 react-native-video

npm install react-native-paper 期间的问题

React Native 查询 GPS 坐标并给出超时