在场景之间导航时,组件无法卸载

时间:2017-04-03 07:33:42

标签: reactjs react-native

编辑:我现在怀疑问题是由here描述的问题引起的。我认为离开场景会再次渲染它,从而使我的组件保持活力。

=========================

我正在构建一个React Native组件,用于侦听NetInfo更改并显示基于react-native-modal的模式对话框。

这是代码:

import React, {Component} from 'react';
import {NetInfo, View, Text, Button, TouchableOpacity} from 'react-native';
import Modal from 'react-native-modal';

export default class WifiCheckModal extends Component {
    constructor() {
        super();
    }

    componentWillMount() {
        console.log('WifiModal mounting');
    }

    componentDidMount() {
        setTimeout(this.refreshConnectionStatus.bind(this), 500);
        NetInfo.addEventListener('change', this._handleConnectivityChange);
    }

    componentWillUnmount() {
        console.log('WifiModal unmounting');
        NetInfo.removeEventListener('change', this._handleConnectivityChange);
        this.isAlive = false;
    }

    _handleConnectivityChange = (connectionStatus) => {
        console.log('IsConnected = ' + connectionStatus);
        // Need to handle 'WIFI' on Android and 'wifi' on iOS, so convert to lowercase.
        let isOnWifi = (connectionStatus.toLowerCase() === 'wifi');
        let shouldShowModal = !isOnWifi;

        if (this.state.showModal != shouldShowModal) {
            console.log('Changing modal state to ' + shouldShowModal + ' because connection is ' + connectionStatus);
            this.setState({showModal: !isOnWifi});
        }
    }

    render() {
        return (
            <Modal isVisible={this.state.showModal}>
                <View style={styles.modalContent}>
                    <Text>You must be connected to wifi to use this app.</Text>
                    <TouchableOpacity onPress={this.refreshConnectionStatus.bind(this)}>
                        <View style={styles.button}>
                            <Text>Check again</Text>
                        </View>
                    </TouchableOpacity>
                </View>
            </Modal>
        );
    }

    refreshConnectionStatus() {
        NetInfo.fetch().then(connectionStatus => this._handleConnectivityChange(connectionStatus));
    }
}

然后我在用作场景的其他组件的render方法中使用此组件:

class SomeComponentScene extends Component {

    // ...

    render() {
        return (
            <View><WifiCheckModal /> ... </View>
        );
    }
}

导航代码位于我的index.js(从index.android.js导入)中,如下所示:

export default class App extends Component {
    constructor() {
        super();
    }

    render() {
        if (Platform.OS === 'android') {
            BackAndroid.addEventListener('hardwareBackPress', () => {
                console.log("Android back pressed");

                if (_navigator.getCurrentRoutes().length === 1  ) {
                    return false;
                }

                _navigator.pop();
                return true;
            });
        }

        return (<Navigator
            initialRoute={{ index: 0, name: 'Splash'}}
            renderScene={ this.navigateToScene }/>);
    }

    navigateToScene(route, navigator) {
        console.log("navigateToScene " + JSON.stringify(route));

        _navigator = navigator;

        if (route.name == 'Splash') {
            return <SplashScene
                navigator={navigator}
                onRequireAuthentication={() => {
                    navigator.replaceAtIndex({name: 'Login'}, 0);
                }}
                onNotRequireAuthentication={() => {
                    navigator.replaceAtIndex({name: 'List'}, 0);
                }}/>
        } else if (route.name == 'Login') {
            return <LoginScene
                navigator={navigator}
                onAuthenticationCompleted={() => {
                    navigator.replaceAtIndex({name: 'List'}, 0);
                }}/>
        } else if (route.name == 'List') {
            return <ListScene
                navigator={navigator}/>
        } else if (route.name == 'Add') {
            return <AddScene
                navigator={navigator}/>
        } else if (route.name == 'Chat') {
            return <ChatScene
                navigator={navigator}
                data={route.data}/>
        } else if (route.name == 'Map') {
            return <MapScene
                navigator={navigator}
                data={route.data}/>
        }
    }
}

我注意到,当我在场景之间移动时,模式的componentDidUnmount并不总是被调用,让多个听众都在监听NetInfo更改。

在场景之间移动时是否未卸载组件?或者也许我正在做的事情让我的组件保持活力?还有另一种方法我应该检测到我的组件不再处于查看状态,因此应该从NetInfo取消注册吗?

或许或许我什么都不担心,拥有多个听众并且他们最终都会被清理好了吗?

0 个答案:

没有答案