Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
539 views
in Technique[技术] by (71.8m points)

javascript - React Navigation Is there a way to refer to a navigator from the parent component?

I understand that navigation and route props are automatically passed to the target screen when you navigate. So you can access navigation when you're in that screen, say screen B.

What I want to do is in Screen A, where the navigator is defined, I'd like to be able to setParams every so often. How can I refer to the navigator in this case?

For example, I would like to do this:

navigator.screen('posts').setParams({videoData: stuff});

A.js

const A = () => {
  const Tab = createMaterialTopTabNavigator();
  const navigator =   <Tab.Navigator>
  <Tab.Screen name="posts" component={FeedList} />
  </Tab.Navigator>;

  useEffect(()=> {
    fetchStuff((stuff)=> {
      navigator.screen('posts').setParams({videoData: dataState});
    });
  },[]);

  return <>{navigator}</>;
}

Inside the useEffect, I ideally would be able to dynamically set the route params of the target screen.

I tried using initialParams and a state, but the initialParams doesn't seem to update in the target screen when the state changes. (So, I would accept that as an answer too, if you know why that's not working.)

not working initialParams example:


const A = () => {
  const [dataState, setDataState] = useState(null);
  const Tab = createMaterialTopTabNavigator();

  useEffect(()=> {
    fetchStuff((stuff)=> {
      setDataState(stuff);  // this doesn't seem to update initialParams
    });
  },[]);

  return <Tab.Navigator>
  <Tab.Screen name="posts" component={FeedList} initialParams={{videoData: dataState}} />
  </Tab.Navigator>;
}


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can use setParams function.

Here is the code of updating of the state of a nested tab's screen after 3 seconds.

import React, {useContext, useState, createContext, useEffect} from 'react';
import {View, Text, StyleSheet} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {createStackNavigator} from '@react-navigation/stack';
import {CommonActions} from '@react-navigation/native';

const Stack = createStackNavigator();
const KeyContext = createContext();
const DELAY_TIME = 3000;

const KeyContextProvider = (props) => {
  const [routeKey, setRouteKey] = useState(null);
  return (
    <KeyContext.Provider
      value={{key: routeKey, setKey: (value) => setRouteKey(value)}}>
      {props.children}
    </KeyContext.Provider>
  );
};

const AScreen = ({navigation}) => {
  const Tab = createBottomTabNavigator();
  const {key} = useContext(KeyContext);
  React.useEffect(() => {
    if (key) {
      setTimeout(() => {
        navigation.dispatch({
          ...CommonActions.setParams({value: 'Updated state'}),
          source: key,
        });
      }, DELAY_TIME);
    }
  }, [navigation, key]);

  return (
    <Tab.Navigator>
      <Tab.Screen
        name="screen B"
        component={BScreen}
        initialParams={{value: 'Initial state'}}
      />
      <Tab.Screen name="screen C" component={CScreen} />
    </Tab.Navigator>
  );
};

const BScreen = ({route}) => {
  const val = route.params?.value || null;
  const {setKey} = useContext(KeyContext);

  useEffect(() => {
    setKey(route.key);
  }, [route, setKey]);

  return (
    <View style={styles.screen}>
      <Text>Screen B</Text>
      <Text>{val}</Text>
    </View>
  );
};

const CScreen = () => {
  return (
    <View style={styles.screen}>
      <Text>Screen C</Text>
    </View>
  );
};

export default function App() {
  return (
    <KeyContextProvider>
      <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen name="Screen A" component={AScreen} />
        </Stack.Navigator>
      </NavigationContainer>
    </KeyContextProvider>
  );
}

const styles = StyleSheet.create({
  screen: {flex: 1, justifyContent: 'center', alignItems: 'center'},
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...