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

How do I pass props from top navigation to screen within a nested navigation in react navigation 5

我有一个嵌套导航器设置的情况。 app.js 保持 loggedIn 状态,导航器开始为 startnav 在 app.js 中被调用,传递 loggedIn 状态:

    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 loggedIn=true 中设置状态。登录成功后,我需要打开包含登录应用程序屏幕的 MainContainer。

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

我正在使用 React 导航 5。

我认为您可以使用上下文 (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>
    )
  }
}