如何在React导航5的嵌套导航中将道具从顶部导航传递到屏幕

时间:2020-05-18 00:56:07

标签: reactjs react-native react-navigation react-navigation-v5

我有一个嵌套导航器设置的情况。 app.js保持loginIn状态,导航器启动,并通过loginIn状态在app.js中调用startnav:

    class StartupNav extends Component {
  constructor(props) {
    super(props);
    console.log(props.loggedIn);
  }

  render() {
    return (
      <NavigationContainer independent={true}>
        <Stack.Navigator>
          {this.props.loggedIn ? (
            <>
              <Stack.Screen name="MainContainer" component={MainContainer} />
            </>
          ) : (
            <Stack.Screen
              name="AuthStack"
              component={AuthStack}
              params="that" //props pass attempt which isnt successful
            />
          )}
        </Stack.Navigator>
      </NavigationContainer>
    );
  }
}

export default StartupNav;

authStack将登录部分保存为:

   class AuthStack extends Component {
  constructor(props) {
    super(props);
    console.log('props from authstack', props);
  }
  render() {
    return (
      <NavigationContainer independent={true}>
        <Stack.Navigator>
          <Stack.Screen name="Login" component={Login} />
          <Stack.Screen name="ForgotPassword" component={ForgotPassword} />
        </Stack.Navigator>
      </NavigationContainer>
    );
  }
}

然后出现登录屏幕,我在其中执行登录逻辑,并尝试在app.js中设置状态loggingIn = true。登录成功后,我需要打开MainContainer,其中包含已登录的应用程序屏幕。

我无法将props从上层的navScreen传递到下层,因此登录成功后我可以调用prop函数。我像往常一样尝试了代码中的注释,但这甚至无效。 任何人都可以阐明这一点,或者将我指向正确的方向。

我正在使用反应导航5。

1 个答案:

答案 0 :(得分:1)

我认为您可以使用上下文(https://reactjs.org/docs/context.html

我在https://snack.expo.io/wzqRLEbi4

const LoginContext = React.createContext({
  loggedIn: false,
  setLogin: () => {},
  setLogout: () => {}
});

export default class App extends Component {

  constructor(props) {
    super(props);
    this.setLogin = () => {
      this.setState({
        loggedIn: true
      })
    };

    this.setLogout = () => {
      this.setState({
        loggedIn: false
      })
    };

    // State also contains the updater function so it will
    // be passed down into the context provider
    this.state = {
      loggedIn: false,
      setLogin: this.setLogin,
      setLogout: this.setLogout
    };
  }

  render() {
    return (
      <LoginContext.Provider value={this.state}>
        <NavigationContainer independent={true}>
            <Stack.Navigator>
              {this.state.loggedIn ? (
                <>
                  <Stack.Screen name="MainContainer" component={MainContainer} />
                </>
              ) : (
                <Stack.Screen
                  name="AuthStack"
                  component={AuthStack}
                  params="that" //props pass attempt which isnt successful
                />
              )}
            </Stack.Navigator>
          </NavigationContainer>
        </LoginContext.Provider>
    );
  }
}

class Login extends Component {
  tryLogin = (setLogin) => {
    // your login logic 
    let isLoginSuccess = true;

    // if success
    setLogin();
  }
  render() {
    return (
      <LoginContext.Consumer>
      {({setLogin}) => (
        <View style={{justifyContent: 'center', alignItems: 'center'}}>
        <TouchableOpacity onPress={() => this.tryLogin(setLogin)}><Text>Login</Text></TouchableOpacity>
      </View>
      )}
      </LoginContext.Consumer>
    )
  }
}