编辑:我现在怀疑问题是由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
取消注册吗?