更新
有人在以下答案中建议链式三元语句,但恐怕这行不通。我已经在下面复制了他们的解决方案的版本。错误是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>
);
};
答案 0 :(得分:0)
尝试链接三元运算符有两个潜在问题:
条件不是互斥的,因此同一屏幕将呈现多次。
同一屏幕在多个三元运算符的“ 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
逻辑可以是您要完成工作的任何逻辑。这样可以将逻辑与实际渲染完全分开。