导航到不同屏幕时如何断开套接字

iRo*_*tia 5 sockets reactjs react-native

我正在使用socket.io-client来获取加密货币的最新数据

constructor() {
    super();
      this.socket = openSocket('https://coincap.io');
    }
Run Code Online (Sandbox Code Playgroud)

然后调用它componentDidMount

 componentDidMount() {
    this.socket.on('trades', (tradeMsg) => {
          for (let i=0; i< this.updateCoinData.length; i++) {
             console.log("it is being called still")
              if (this.updateCoinData[i]["short"] == tradeMsg.coin ) {
                  this.updateCoinData[i]["price"] = tradeMsg["message"]['msg']['price']
                  //Update the crypto Value state in Redux
                  this.props.updateCrypto(this.updateCoinData);
              }
          }
      })
Run Code Online (Sandbox Code Playgroud)

由于套接字已打开,因此它将继续发出消息。现在我想当我从一个屏幕导航到另一个屏幕时,套接字连接将断开,因此我正在做这样的事情

componentWillUnmount() {
 this.socket.disconnect();
}
Run Code Online (Sandbox Code Playgroud)

但即使我已经导航到不同的页面,我的套接字仍在继续发出信号,这意味着它仍然处于连接状态。

我不确定这是否是因为react-navigation我在这里使用StackNavigator

这是我的react-navigation组件

export const MyScreen = createStackNavigator({
  Home: { 
    screen: CoinCap
  },
  CoinCapCharts: {
     screen: CoinCapCharts
    },
  CurrencySelection: {
    screen: CurrencySelection
  },
  CoinChart: {
    screen: CoinChart
  },
  News: {
    screen: News
  }

},{
    initialRouteName: 'Home',
    headerMode: 'none'
});
Run Code Online (Sandbox Code Playgroud)

问题:当用户从一个屏幕导航到另一个屏幕时,如何关闭套接字?并在用户导航到同一给定屏幕时重新打开它?

Jef*_*ang 4

解决方案

1. 调用时首先尝试断开套接字,navigate如下所示。

navigate() {
    this.socket.disconnect();
    this.props.navigation.navigate('CoinCapCharts');
}
Run Code Online (Sandbox Code Playgroud)

2.使用导航生命周期监听器:doc

  • willFocus - 屏幕将聚焦
  • willBlur - 屏幕将失去焦点
  • didFocus - 屏幕聚焦(如果有过渡,则过渡完成)
  • didBlur - 屏幕未聚焦(如果有过渡,则过渡完成)

componentDidMount() {
  this.didFocusSubscription = this.props.navigation.addListener(
    'willFocus', () => { DO_WHAT_YOU_WANT }
  );
}

componentWillUnmout() {
    this.didFocusSubscription.remove();
}
Run Code Online (Sandbox Code Playgroud)

为什么?

当您导航屏幕时,尤其是在使用时,无法保证屏幕组件的卸载StackNavigation。因为StackNavigation对屏幕的堆栈使用push和pop,并且当另一个屏幕被push时,前一个屏幕不会被卸载。