Home > Software design >  Passing function to throw Stack.Screen in react navigation
Passing function to throw Stack.Screen in react navigation

Time:07-19

I'm attempting to pass a useState function between screens. I receive this function on the App.tsx and I passed it to the Navigator handler, to I can pass the set parameter into the signInScreen.
This is the app.tsx:

export default function App() {
  // Autentication
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  useEffect(() => {
    setLocale('pt');

    auth.onAuthStateChanged((user) => {
      if (user) {
        if (user?.emailVerified) {
          setIsAuthenticated(true);
        }
      }
    });
  }, []);

  if (!fontsLoaded) return <></>;

  return (
    <ThemeProvider theme={theme}>
      {!isAuthenticated ? (
        <NavigationContainer>
          <AuthRoutes setIsAuthenticated={setIsAuthenticated} />
        </NavigationContainer>
      ) : (
        <Provider store={store}>
          <Main />
        </Provider>
      )}
      <ToastMessage />
    </ThemeProvider>
  );
}

The route, this is how I attemtped to pass the function:

import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { SignIn } from '../screens/SignIn';
import { Register } from '../screens/Register';
import { Welcome } from '../screens/Welcome';
import { ForgotPassword } from '../screens/ForgotPassword';

export function AuthRoutes({ setIsAuthenticated }: any) {
  const { Navigator, Screen } = createStackNavigator();

  return (
    <Navigator screenOptions={{ headerShown: false }} initialRouteName="Welcome">
      <Screen key="Welcome" name="Welcome" component={Welcome} />
      <Screen key="SignIn" name="SignIn" component={SignIn} options={setIsAuthenticated}/>
      <Screen key="SignUp" name="SignUp" component={Register} />
      <Screen key="ForgotPassword" name="ForgotPassword" component={ForgotPassword} />
    </Navigator>
  );
}

On the signIn I attempted to access the props, but the function wasn't there:

import React, { useEffect, useState } from 'react';
import ArrowBack from '../../assets/arrowBack.svg';
import { Keyboard, TouchableWithoutFeedback } from 'react-native';
import { Form } from '../../components/FormSignIn';
import {
  Container,
  TitleContainer,
  Title,
  ArrowContainer,
  ArrowTouchable,
  ForgotPasswordContainer,
  ForgotPasswordTouchable,
  ForgotPasswordText,
  TextContainer,
  Text,
  TouchableText,
  SignUpText,
} from './styles';
import i18n from 'i18n-js';
import { Modal } from '../../components/Modal';

export function SignIn({ navigation, ...props }: any) {
  const [forgotEmail, setForgotEmail] = useState('');
  const [showModal, setShowModal] = useState(false);

console.log(props)
  return (
    <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
      <>
        <Modal
          visible={showModal}
          text={i18n.t('checkEmail.emailSent')}
          state="success"
          description={i18n.t('checkEmail.description')}
          buttonText={i18n.t('checkEmail.sendAgain')}
          navigation={undefined}
          setShowModal={setShowModal}
          onPress={() => console.log('[pre')}
        />
        <Container>
          <ArrowContainer>
            <ArrowTouchable onPress={() => navigation.goBack(null)}>
              <ArrowBack width={24} height={24} />
            </ArrowTouchable>
          </ArrowContainer>

          <TitleContainer>
            <Title>{i18n.t('login.title')}</Title>
          </TitleContainer>

          <Form setForgotEmail={setForgotEmail} setShowModal={setShowModal} />

          <ForgotPasswordContainer>
            <ForgotPasswordTouchable
              onPress={() => navigation.navigate('ForgotPassword', { forgotEmail })}
            >
              <ForgotPasswordText>{i18n.t('login.forgotPassword')}</ForgotPasswordText>
            </ForgotPasswordTouchable>
          </ForgotPasswordContainer>

          <TextContainer>
            <Text>{i18n.t('login.createAccount')}</Text>
            <TouchableText onPress={() => navigation.navigate('SignUp')}>
              <SignUpText>{i18n.t('login.signUp')}</SignUpText>
            </TouchableText>
          </TextContainer>
        </Container>
      </>
    </TouchableWithoutFeedback>
  );
}

CodePudding user response:

In the AuthRoutes-file you are passing the hook setIsAuthenticated inside the options of the Navigator.Screen instead of a prop to the SingIn-component itself. Try to re-factor AuthRoutes to this:

 ...
 return (
    <Navigator screenOptions={{ headerShown: false }} initialRouteName="Welcome">
      <Screen key="Welcome" name="Welcome" component={Welcome} />
      <Screen key="SignIn" name="SignIn" >
          {(props) => <SignIn setIsAuthenticated={setIsAuthenticated} {...props} />}
      </Screen>
      <Screen key="SignUp" name="SignUp" component={Register} />
      <Screen key="ForgotPassword" name="ForgotPassword" component={ForgotPassword} />
    </Navigator>
  );
...

The options prop in Navigator.Screen is not intended for passing variables to the screen, but to specify how the screen is displayed within the navigator. See more here

  • Related