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

问题描述 投票:3回答:3

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

问题是,如何从屏幕到屏幕访问“在线用户”状态,这样每当我收到“用户加入”事件时,我都可以看到更新的在线用户列表?

屏幕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来处理导航

react-native socket.io react-navigation
3个回答
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

 }

0
投票

今年早些时候遇到类似的问题时,我遇到了这个帖子,所以我想我会发布我的解决方案。

我想说在这种情况下你最好的选择是使用自定义导航器来包装你的TabNavigator,它将在你的自定义导航器中公开<TabNavigator />,允许你传递任何方法或状态为ScreenAScreenBscreenProps

自定义导航器看起来像:

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转换为表示组件。


-1
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.