React Navigation:在TabNavigator中的两个屏幕之间共享状态

时间:2018-01-18 03:04:52

标签: react-native socket.io react-navigation

我通过构建简单的聊天应用程序来学习本机。我有两个屏幕包裹在TabNavigator中,第一个屏幕(屏幕A)是聊天框,另一个屏幕(屏幕B)显示在线用户列表。我使用SocketIO来获取这些用户。

问题是,如何访问" onlineUsers"从ScreenA到ScreenB的状态,这样每当我收到一个"用户加入"时,我就能看到更新的在线用户列表。事件

屏幕A:

export default class ScreenA extends Component {
  constructor(props) {
    super(props);

    this.state = {
      onlineUsers = [];
    }
  }

  componentDidMount() {
    // Update list of online users when new user joins chat
    this.socket.on('user joins', (payload) => {
      this.setState({
        onlineUsers: payload.users
      })
    })
  }
}

屏幕B:

export default class ScreenB extends Component {
  constructor(props) {
    super(props);

    // I want to get the onlineUsers from ScreenA
    this.state = {
      onlineUsers = [];
    }
  }
}

路由器:

export const Chat = TabNavigator({
  ChatBox: {
   screen: ScreenA
  },
  OnlineUsers: {
   screen: ScreenB
  },
})

PS:我使用react-navigation来处理导航

3 个答案:

答案 0 :(得分:3)

最好的方法是处理父组件中的事件,然后将其传递给子组件。因此,在您的情况下,您应该在路由器中有一个在线用户列表。然后将数组传递给屏幕B.这是你应该怎么做

<强>路由器

state = {
    online_users:[]
}

_update = (data) => {
    this.setState({online_users:data});
};

export const Chat = TabNavigator({
   ChatBox: {
       screen: <ScreenA onUpdate={this._update}/>
    },
    OnlineUsers: {
       screen: <ScreenB userList={this.state.online_users}>
    },
})

屏幕A

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

    componentDidMount() {
        // Update list of online users when new user joins chat
        this.socket.on('user joins', (payload) => {
            this.props.onUpdate(payload.users)
        })
    }
}

屏幕B

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

    // You can access online user using this.props.userList

 }

答案 1 :(得分:0)

今年早些时候遇到类似问题时,我碰到了这篇文章,所以我想我应该发布解决方案。

在这种情况下,我最好的选择是使用“自定义导航器”包装TabNavigator,该标签导航器将在自定义导航器中显示<TabNavigator />,使您可以将任何方法或状态传递给ScreenA,然后ScreenBscreenProps

自定义导航器如下所示:

import React from 'react'
import { ChatTabNavigator } from './ChatTabNavigator'

class StateManagingCustomNavigator extends React.Component {
  static router = ChatTabNavigator.router

  state = {
    onlineStatus: [theStatus]
  }

  handleMessagePosted = () => {
    // Handle message post, etc...
  }

  // ... SocketIO code and other logic to manage the state here? ...

  render() {
    const { navigation } = this.props
    const { onlineStatus } = this.state

    return (
      <ChatTabNavigator
       screenProps={{
         theStatus: onlineStatus,
         chatMessagePosted: this.handleMessagePosted
       }}
       navigation={navigation}
      />
    )
  }
}

export default StateManagingCustomNavigator

在这里,您可以按照@Ashish Prakash的建议实施事件系统,或者在自定义导航器中管理所有状态,并将ScreenAScreenB转换为演示组件。

答案 2 :(得分:-1)

从服务器获取用户列表时使用this.props.navigation.setParam({onlineUsers: onlineUsers: payload.users})

然后在屏幕B中使用它,如this.props.navigation.state.params.onlineUsers