自定义 DrawerNavigator
Custom DrawerNavigator
我正在尝试创建一个自定义 DrawerNavigator,其中的项目 shown/hidden 取决于
在 redux 存储状态上。我是 react-native 的新手 :)
到目前为止,我所有的尝试都导致了错误。正如 'Providing a custom drawerContent'-docs 所示,我的最后一次尝试是创建这样的自定义内容(我将其更改为功能组件)
const MainDrawerNavigator = createDrawerNavigator();
export const MainNavigator = state => {
const user = useSelector(state => state.user.user);
//next console lines give different output , i also tried to use useEffect() function but no luck
// console.log("=================state===================");
// console.log(user);
// console.log("===================state=================");
const dispatch = useDispatch();
const isTrainer = useSelector(state => state.user.user.isTrainer) === null ? false : true);
return (
{isTrainer &&
<MainDrawerNavigator.Screen
name="AddUser"
component={AddUserNavigator}
options={{
drawerIcon: props => (
<Ionicons
name={Platform.OS === "android" ? "md-cart" : "ios-cart"}
size={23}
color={props.color}
/>
)
}}
/>
}
<MainDrawerNavigator.Screen
name="Ereignis hinzufügen"
component={MainNavigator}
options={{
drawerIcon: props => (
<Ionicons
name={Platform.OS === "android" ? "md-cart" : "ios-cart"}
size={23}
color={props.color}
/>
)
}}
/>
<MainDrawerNavigator.Screen
title="Deine Daten"
name="UserProfil"
component={UserProfilNavigator}
options={{
drawerIcon: props => (
<Ionicons
name={Platform.OS === "android" ? "md-person" : "md-person"}
size={23}
color={props.color}
/>
)
}}
/>
</MainDrawerNavigator.Navigator>
);
};
因此用户登录 redux 存储是为了设置用户数据(一切正常)并且抽屉应该考虑用户可能拥有的角色并仅显示可能的路线。希望我解释清楚,有人可以在正确的方向给出提示。
谢谢
英戈
编辑:
我通过使用以下代码实现这个
import React from "react";
import { useSelector } from "react-redux";
import { NavigationContainer } from "@react-navigation/native";
import {
MainNavigator,
AuthNavigator
} from "./MainNavigator";
const AppNavigator = props => {
const isAuth = useSelector(state => !!state.auth.token);
const didTryAutoLogin = useSelector(state => state.auth.didTryAutoLogin);
return (
<NavigationContainer>
{isAuth && <MainNavigator />}
{!isAuth && didTryAutoLogin && <AuthNavigator />}
</NavigationContainer>
);
};
export default AppNavigator;
主要是 App.js
export default function App() {
const [fontLoaded, setFontLoaded] = useState(false);
if (!fontLoaded) {
return (
<AppLoading
startAsync={fetchFonts}
onFinish={() => {
setFontLoaded(true);
}}
/>
);
}
return (
<Provider store={store}>
<AppNavigator />
</Provider>
);
}
我认为最初的问题是 "state" 变量的名称冲突。您应该在 main 函数之外定义您的选择器函数,这样它就不会在每次渲染时都重新计算。 useSelector 钩子为选择器函数提供了 redux 状态,它没有作为道具提供给 MainNavigator。您还可以使用单个选择器来创建 "isTrainer" 布尔值:
// ensuring that user exists in state, and that user.user.isTrainer is true.
const selectUserIsTrainer = state => state.user.user && state.user.user.isTrainer
export const MainNavigator = ({...props}) => {
const userIsTrainer = useSelector(selectUser)
return userIsTrainer ? <TrainerNavigator /> : <NonTrainerNavigator />
}
如果我是对的,您只是想隐藏抽屉中的某些物品?如果是,请查看下面我们使用的内容!
const Item = (props) => {
return (
<View>
<TouchableNativeFeedback onPress={props.onPress}>
<Text>{props.title}</Text>
</TouchableNativeFeedback>
</View>
);
};
const MyDrawer = () => {
const [viewable, setViable] = useState({showScreen1: false, showScreen2: true});
// Do some wizardry which determines what state to show
// Yes yes... wizard... wohoo :D
// Okay done now
return (
<Drawer.Navigator
drawerContent={({navigation}) => (
<SafeAreaView>
<ScrollView>
{
viewable.showScreen1 && (
<Item
title="Some Screen 1"
onPress={() => navigation.navigate('someScreen1')}
/>
)
}
{
viewable.showScreen2 && (
<Item
title="Some Screen 2"
onPress={() => navigation.navigate('someScreen1')}
/>
)
}
</ScrollView>
</SafeAreaView>
)}
>
<Drawer.Screen
component={SomeScreen1}
name="someScreen1"
/>
<Drawer.Screen
component={SomeScreen2}
name="someScreen2"
/>
</Drawer.Navigator>
);
};
请注意,我对 redux
一无所知,但我认为您会设法自行创建状态和连贯条件:)
我正在尝试创建一个自定义 DrawerNavigator,其中的项目 shown/hidden 取决于 在 redux 存储状态上。我是 react-native 的新手 :)
到目前为止,我所有的尝试都导致了错误。正如 'Providing a custom drawerContent'-docs 所示,我的最后一次尝试是创建这样的自定义内容(我将其更改为功能组件)
const MainDrawerNavigator = createDrawerNavigator();
export const MainNavigator = state => {
const user = useSelector(state => state.user.user);
//next console lines give different output , i also tried to use useEffect() function but no luck
// console.log("=================state===================");
// console.log(user);
// console.log("===================state=================");
const dispatch = useDispatch();
const isTrainer = useSelector(state => state.user.user.isTrainer) === null ? false : true);
return (
{isTrainer &&
<MainDrawerNavigator.Screen
name="AddUser"
component={AddUserNavigator}
options={{
drawerIcon: props => (
<Ionicons
name={Platform.OS === "android" ? "md-cart" : "ios-cart"}
size={23}
color={props.color}
/>
)
}}
/>
}
<MainDrawerNavigator.Screen
name="Ereignis hinzufügen"
component={MainNavigator}
options={{
drawerIcon: props => (
<Ionicons
name={Platform.OS === "android" ? "md-cart" : "ios-cart"}
size={23}
color={props.color}
/>
)
}}
/>
<MainDrawerNavigator.Screen
title="Deine Daten"
name="UserProfil"
component={UserProfilNavigator}
options={{
drawerIcon: props => (
<Ionicons
name={Platform.OS === "android" ? "md-person" : "md-person"}
size={23}
color={props.color}
/>
)
}}
/>
</MainDrawerNavigator.Navigator>
);
};
因此用户登录 redux 存储是为了设置用户数据(一切正常)并且抽屉应该考虑用户可能拥有的角色并仅显示可能的路线。希望我解释清楚,有人可以在正确的方向给出提示。 谢谢 英戈
编辑: 我通过使用以下代码实现这个
import React from "react";
import { useSelector } from "react-redux";
import { NavigationContainer } from "@react-navigation/native";
import {
MainNavigator,
AuthNavigator
} from "./MainNavigator";
const AppNavigator = props => {
const isAuth = useSelector(state => !!state.auth.token);
const didTryAutoLogin = useSelector(state => state.auth.didTryAutoLogin);
return (
<NavigationContainer>
{isAuth && <MainNavigator />}
{!isAuth && didTryAutoLogin && <AuthNavigator />}
</NavigationContainer>
);
};
export default AppNavigator;
主要是 App.js
export default function App() {
const [fontLoaded, setFontLoaded] = useState(false);
if (!fontLoaded) {
return (
<AppLoading
startAsync={fetchFonts}
onFinish={() => {
setFontLoaded(true);
}}
/>
);
}
return (
<Provider store={store}>
<AppNavigator />
</Provider>
);
}
我认为最初的问题是 "state" 变量的名称冲突。您应该在 main 函数之外定义您的选择器函数,这样它就不会在每次渲染时都重新计算。 useSelector 钩子为选择器函数提供了 redux 状态,它没有作为道具提供给 MainNavigator。您还可以使用单个选择器来创建 "isTrainer" 布尔值:
// ensuring that user exists in state, and that user.user.isTrainer is true.
const selectUserIsTrainer = state => state.user.user && state.user.user.isTrainer
export const MainNavigator = ({...props}) => {
const userIsTrainer = useSelector(selectUser)
return userIsTrainer ? <TrainerNavigator /> : <NonTrainerNavigator />
}
如果我是对的,您只是想隐藏抽屉中的某些物品?如果是,请查看下面我们使用的内容!
const Item = (props) => {
return (
<View>
<TouchableNativeFeedback onPress={props.onPress}>
<Text>{props.title}</Text>
</TouchableNativeFeedback>
</View>
);
};
const MyDrawer = () => {
const [viewable, setViable] = useState({showScreen1: false, showScreen2: true});
// Do some wizardry which determines what state to show
// Yes yes... wizard... wohoo :D
// Okay done now
return (
<Drawer.Navigator
drawerContent={({navigation}) => (
<SafeAreaView>
<ScrollView>
{
viewable.showScreen1 && (
<Item
title="Some Screen 1"
onPress={() => navigation.navigate('someScreen1')}
/>
)
}
{
viewable.showScreen2 && (
<Item
title="Some Screen 2"
onPress={() => navigation.navigate('someScreen1')}
/>
)
}
</ScrollView>
</SafeAreaView>
)}
>
<Drawer.Screen
component={SomeScreen1}
name="someScreen1"
/>
<Drawer.Screen
component={SomeScreen2}
name="someScreen2"
/>
</Drawer.Navigator>
);
};
请注意,我对 redux
一无所知,但我认为您会设法自行创建状态和连贯条件:)