如何根据状态变量渲染屏幕?

时间:2020-08-26 17:19:00

标签: javascript react-native

更新

有人在以下答案中建议链式三元语句,但恐怕这行不通。我已经在下面复制了他们的解决方案的版本。错误是done()

expect

我们的应用程序使用React Native 0.63.2和React Navigation v5。我们只使用带有钩子的功能组件,没有类。

我需要根据以下状态找到一种方法来渲染以下屏幕:

  • 如果hasSelectedLanguage和hasCompletedIntro都为真,则应转到主屏幕。

  • hasSelectedLanguage为true,而hasCompletedIntro为false,则应转到WelcomeScreen。

  • hasSelectedLanguage为假,应转到ChooseYourLanguageScreen。

正如您在代码片段中看到的那样,我已经找到了一种根据setTimeout的布尔状态渲染屏幕的方法,但是当我尝试链接三元语句时,React Navigation 5会引发错误。我被卡住了。

我很想知道如何渲染屏幕以解决上面的要点,同时还要保留与代码中已经存在的 Error: A navigator cannot contain multiple 'Screen' components with the same name (found duplicate screen named 'Welcome')三元关联的导航。

// This is the root stack navigator.
// It is currently the main skeleton of the navigation logic

const RootStack = createStackNavigator();

const RootStackScreen = () => {
  React.useEffect(() => {
    SplashScreen.hide();
  }, []);

  const [hasCompletedIntro, setHasCompletedIntro] = React.useState(false);
  const [hasSelectedLanguage, setHasSelectedLanguage] = React.useState(true);

  return (
    <RootStack.Navigator>
      {hasSelectedLanguage ? (
        <>
          <RootStack.Screen name="Welcome" component={WelcomeScreen} />
          <RootStack.Screen
            name="HowToUseThisApp"
            component={HowToUseThisAppScreen}
          />
          <RootStack.Screen name="Home" component={AppTabsScreen} />
        </>
      ) : (
        <RootStack.Screen
          name="Choose Your Language"
          component={ChooseYourLanguageScreen}
        />
      )}
      {!hasCompletedIntro && hasSelectedLanguage ? (
        <>
          <RootStack.Screen name="Welcome" component={WelcomeScreen} />
          <RootStack.Screen
            name="HowToUseThisApp"
            component={HowToUseThisAppScreen}
          />
          <RootStack.Screen name="Home" component={AppTabsScreen} />
        </>
      ) : (
        <RootStack.Screen name="Home" component={AppTabsScreen} />
      )}
    </RootStack.Navigator>
  );
};

1 个答案:

答案 0 :(得分:0)

尝试链接三元运算符有两个潜在问题:

  1. 条件不是互斥的,因此同一屏幕将呈现多次。

  2. 同一屏幕在多个三元运算符的“ else”分支中呈现。

解决方案是删除重复项。

最简单的方法是确保所有条件都是互斥的,并且每个“ else”分支均呈现唯一的屏幕。现在,您的条件是hasSelectedLanguage!hasCompletedIntro && hasSelectedLanguage,它们可以同时满足。在Insead中,您可以将它们分别更改为hasCompletedIntro && hasSelectedLanguage!hasCompletedIntro && hasSelectedLanguage(不能同时满足您的口头描述)。

一种解决方案是嵌套三元运算符,以便仅执行一个分支:

{ <condition1> ? <screens> : (<condition2> ? <screens> : <screens>)}

但是当您用实际的JSX填写时,嵌套和缩进将是可怕的。相反,我建议在return之前使用JavaScript代码:

render() {
    let screens = <default screens>;
    if (<condition1>) {
        screens = <screens>;
    } else if (<condition2>) {
        screens = <screens>;
    }

    return (
        <RootStack.Navigator>
            {screens}
        </RootStack.Navigator>
    ;
}

if逻辑可以是您要完成工作的任何逻辑。这样可以将逻辑与实际渲染完全分开。