React Navigation - How to pass data across different screens in TabNavigator?

后端 未结 5 1947
野的像风
野的像风 2021-01-14 06:17

I have a TabNavigator, and in each tab is a StackNavigator. Inside the StackNavigator, I have screens. The screens in each Tab do not call each other directly; the TabNaviga

相关标签:
5条回答
  • 2021-01-14 06:42

    It may seem that this.props.navigation.state.params is only able to old one parameter? Possibly? Try this:

        doIt = () => {
        this.props.navigation.setParams({results: 'one'});   // <--- set data when user clicks button.
      }
    
    
    console.log(this.props.navigation.state.params.results);
    
    0 讨论(0)
  • 2021-01-14 06:48

    @tempomax tried same with AsyncStorage but data came in with a delay. Sometimes you don't need Redux if your app stays small.

    So tried to find a way without Redux. Here is what I came up with

    I hope it's not too late to answer. Solved it with NavigationEvents and setting params to Route.

    The problem with tab is that you can´t pass params to screen because navigation.navigate will be triggered automatically if createMaterialTopTabNavigator is swiped or clicked on non-active TabBar Button.

    This can be solved with NavigationEvent like follow.

        import React from 'react';
        import { View } from 'react-native';
        import { NavigationEvents } from 'react-navigation';
    
        const MyScreen = () => (
          <View>
            <NavigationEvents
              onWillFocus={payload => console.log('will focus',payload)}
              onDidFocus={payload => console.log('did focus',payload)}
              onWillBlur={payload => 
                 /*
                  if screen is about to change this will be triggred
                  In screen 'MyScreen2' you can get it with navigation.params
                 */
                  this.props.navigation.navigate('MyScreen2', { name: 'Brent' })
              }
              onDidBlur={payload => console.log('did blur',payload)}
            />
            {/* 
              Your view code
            */}
          </View>
        );
    
        export default MyScreen;
    

    Now you can get the data in MyScreen2

     /* 2. Get the param, provide a fallback value if not available */
    const { navigation } = this.props;
    const itemId = navigation.getParam('name', 'DefaultName');
    const otherParam = navigation.getParam('otherParam', 'some default value');
    
    0 讨论(0)
  • 2021-01-14 06:51

    If you are using React Native Navigation Version 5.x with a DrawerNavigation, you can do this using

    in screen 1:

     <Button
                onPress={() => { 
                this.props.navigation.navigate(<ScreenNameOfDrawerScreen>,
    {screen:'<ScreenNameInTabDrawer>',params:{your_json_Data}});
                            }} />
    

    in screen 2:

      ............
         render() {
        
        if(this.props.route.params!=undefined){
                if(this.props.route.params.your_json_Data!=null){
                 //    Use this.props.route.params.your_json_Data. It is your json data.
     }
              
        }
          
              
                return (
        ..............
    
    0 讨论(0)
  • 2021-01-14 06:57

    I came across a similar problem. I had a multi page form that the client insisted on having each step be enclosed in a tab on a tab bar. I used the react navigation createMaterialTopTabNavigator to create the navigator and couldn't find an easy way to pass the form data between tabs.

    What I end up doing was using react's Context API and wrapped the tab navigator in a root form container that provides the context value to the navigator and routes inside. Here is how I did it:

    Root form container

    // MultiScreenForm.js
    imports...
    import MultiScreenFormNavigator from './MultiScreenFormNavigator'
    
    export const FormContext = React.createContext()
    
    class MultiScreenForm extends Component {
      constructor(props) {
        super(props)
        this.state = {
          // formDataHere
          formUpdaters: {
               onToggleOptIn: this.handleToggleOptIn // example updater method
               // other
            }
          }
       }
        handleToggleOptIn = () => {
        // toggle opt in form data with this.setState
      }
    
      render() {
        return (
          <FormContext.Provider value={this.state}>
            <MultiScreenFormNavigator />
          </FormContext.Provider>
        )
      }
    }
    
    export default MultiScreenForm
    

    Example form page

    // ProfileForm.js
    imports...
    import { FormContext } from './MultiScreenForm'
    
    class ProfileForm extends Component {
      render() {
        // FormContext.Consumer uses function as child pattern
        return (
          <FormContext.Consumer>
            { (context) => (
                 // our form can now use anything that we pass through the context
                 // earlier, we passed the root form's state including an updater
                 <button onPress={context.formUpdaters.onToggleOptIn} />
                 // ...
              )
            }
          </FormContext.Consumer>
        )
      }
    }
    
    export default ProfileForm
    

    Tab navigator

    // MultiScreenFormNavigator.js
    imports...
    import ProfileForm from './ProfileForm'
    import { createMaterialTopTabNavigator } from 'react-navigation'
    
    const MultiScreenFormNavigator = createMaterialTopTabNavigator(
      {
        Profile: ProfileForm,
        // AnotherForm: AnotherForm
      },
      // { navigator options here... }
    )
    
    export default MultiScreenFormNavigator
    

    We then render the MultiScreenForm instead of the tab navigator directly.

    This worked for me but I feel there should be an easier way to do this. I hope people who read this can share their approaches.

    0 讨论(0)
  • 2021-01-14 06:59

    Setting props did not work when passing data across different tabs. I even tried playing with AsyncStorage, trying to save and retrieve them in different tabs.

    I ended up using Redux to save my states, and that has worked well so far.

    0 讨论(0)
提交回复
热议问题