How to pass current state of App to Tab Navigation Screen

冷暖自知 提交于 2020-05-17 07:49:13

问题


If I'm using React Navigation v5, what is the best way to pass the current state of a parent component (in my case, the main App) down through a Tab and Stack navigator to a screen that I'd like to use the current state in?

Following the documentation, I have created a stack navigator for each tab that holds the respective screens.

App.js contains a state that needs to be used for a few things. Most importantly, it will provide badge count on the Tab navigator, as well as be a source of Flatlist data on one of the tab screens.

What is the correct approach to getting the state from App all the way down to a child component in a stack navigator in a tab navigator?

App.js

const Tab = createBottomTabNavigator()

export default class App extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      neededArray: []
    }
  }

  const updateTheArray = (newArray) => {
    this.setState({
      neededArray: newArray
    })
  }

  componentDidMount(){
    //Listener that searches for nearby bluetooth beacons and updates the array with the passed function
    startObserver(updateTheArray)
  }

  componentWillUnmount(){
    stopObserver()
  }

  render(){
    return(
      <NavigationContainer>
        <Tab.Navigator>
          <Tab.Screen
            name = "Home"
            component = { HomeStack }/>
          <Tab.Screen
            name = "About"
            component = { AboutStack }/>

          //The Stack that contains the screen that I need to use the App's state in
          <Tab.Screen
            name = "Nearby"
            component = { NearbyStack }/>
        </Tab.Navigator>
      </NavigationContainer>
    )
  }
}

NearbyStack.js

//This stack holds the screen that I need to use the App's state in

const NearbyStackNav = createStackNav()

const NearbyStack = () => {
  return(
    <NearbyStackNav.Navigator>
      <NearbyStackNav.Screen
        name = "Nearby"
        component = { NearbyScreen }
      />
    </NearbyStackNav.Navigator>
  )
}

NearbyScreen.js

//The screen that I want to use the App's state in
const NearbyScreen = () => {
  return(
    <View>
      <FlatList
        //Where I would like to use the App's state
      />
    </View>
  )
}

回答1:


You can pass some initial params to a screen. If you didn't specify any params when navigating to this screen, the initial params will be used. They are also shallow merged with any params that you pass. Initial params can be specified with an initialParams prop:

Usage

<Tab.Screen
            name = "Nearby"
            component = { NearbyStack }
            initialParams={{ arrayItem: this.state.neededArray }}
 />

NearbyScreen.js

React.useEffect(() => {
    if (route.params?.arrayItem) {
      // Post updated, do something with `route.params.arrayItem`
      // For example, send the arrayItem to the server
    }
  }, [route.params?.arrayItem]);



回答2:


My solution was to use React's Context API.

BeaconContext.js - New

import React from 'react'

const BeaconContext = React.createContext()

export default BeaconContext

App.js - Modified

import BeaconContext from './path/to/BeaconContext'

const Tab = createBottomTabNavigator()

export default class App extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      neededArray: []
    }
  }

  const updateTheArray = (newArray) => {
    this.setState({
      neededArray: newArray
    })
  }

  componentDidMount(){
    startObserver(updateTheArray)
  }

  componentWillUnmount(){
    stopObserver()
  }

  render(){
    return(
      // Wrap the nav container in the newly created context!!!

      <BeaconContext.Provider value = { this.state.neededArray }
        <NavigationContainer>
          <Tab.Navigator>
            <Tab.Screen
              name = "Home"
              component = { HomeStack }/>
            <Tab.Screen
              name = "About"
              component = { AboutStack }/>
            <Tab.Screen
              name = "Nearby"
              component = { NearbyStack }/>
          </Tab.Navigator>
        </NavigationContainer>
      </BeaconContext.Provider>
    )
  }
}

NearbyStack.js - Unchanged

const NearbyStackNav = createStackNav()

const NearbyStack = () => {
  return(
    <NearbyStackNav.Navigator>
      <NearbyStackNav.Screen
        name = "Nearby"
        component = { NearbyScreen }
      />
    </NearbyStackNav.Navigator>
  )
}

NearbyScreen.js - Modified

import BeaconContext from './path/to/BeaconContext'

const NearbyScreen = () => {
  return(
    <View>
      //Wrap the component in the new context's consumer!!!

      <BeaconContext.Consumer>
      {
        context => <Text>{ context }</Text>
      }
      </BeaconContext.Consumer>
    </View>
  )
}


来源:https://stackoverflow.com/questions/60870060/how-to-pass-current-state-of-app-to-tab-navigation-screen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!