Reputation: 167
I'm building an application in which user could see information in different languages. User could also choose a language in which information would be displayed. However, I run into a problem when I try to set a language for my navigation bar. I'm using React Navigation Native to create navigation bar and useContext hook to get chosen language from another component. If I use if statement inside Navigator, I get an error:
Error: Couldn't find any screens for the navigator. Have you defined any screens as its children?
As per my understanding application on mount doesn't get variable "locale" and it doesn't have anything to display. How could I avoid that (should I use async function somewhere?)?
This is my code:
App.js code
function App() {
const [locale, setLocale] = useState("en");
return (
<LanguageContext.Provider value={{ locale, setLocale }}>
<MainContainer />
</LanguageContext.Provider>
);
}
LanguageContext.js
import { createContext } from "react";
export const LanguageContext = createContext("");
MainContainer.js
const profileName = "Profile";
const detailsName = "Details";
const settingsName = "Settings";
const profileNameFR = "P";
const detailsNameFR = "D";
const settingsNameFR = "S";
const Tab = createBottomTabNavigator();
export default function MainContainer() {
const { locale } = useContext(LanguageContext);
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
let rn = route.name;
if (rn === profileName || rn === profileNameFR) {
iconName = focused ? "person" : "person-outline";
} else if (rn === detailsName || rn === detailsNameFR) {
iconName = focused ? "list" : "list-outline";
} else if (rn === settingsName || settingsNameFR) {
iconName = focused ? "settings" : "settings-outline";
}
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: "tomato",
inactiveTintColor: "grey",
tabBarStyle: { padding: 10, height: 60 },
tabBarLabelStyle: { paddingBottom: 10, fontSize: 10 },
style: { padding: 10 },
})}
>
{locale === "en" && (
<>
<Tab.Screen name={profileName} component={ProfileScreen} />
<Tab.Screen name={detailsName} component={DetailsScreen} />
<Tab.Screen name={settingsName} component={SettingsScreen} />
</>
)}
{locale === "fr" && (
<>
<Tab.Screen name={profileNameFR} component={ProfileScreen} />
<Tab.Screen name={detailsNameFR} component={DetailsScreen} />
<Tab.Screen name={settingsNameFR} component={SettingsScreen} />
</>
)}
</Tab.Navigator>
</NavigationContainer>
);
}
Upvotes: 1
Views: 277
Reputation: 167
I totally forgot about useState that I was using to set the language in main component. In the beginning it was
const [locale, setLocale] = useState("");
Which meant that when app was rendering locale variable's value it was empty string. All I needed to do was to set the state to default application's language, which in my case was "en", and then the application will work.
Also I leave my main component just in case somebody wonders how I use useContext in this scenario:
App.js code
function App() {
const [locale, setLocale] = useState("en");
return (
<LanguageContext.Provider value={{ locale, setLocale }}>
<MainContainer />
</LanguageContext.Provider>
);
}
Upvotes: 1