我在抽屉里面临一个问题。我正在寻找一些帮助。正在使用React Navigation 5版本的人。
我正在使用最新的react导航版本,而我的自定义抽屉代码如下
function CustomDrawerContent(props) {
//
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerItem label="Logout" onPress={()=>
Alert.alert(
'Log out',
'Do you want to logout?',
[
{text: 'Cancel', onPress: () => {return null}},
{text: 'Confirm', onPress: () => {
AsyncStorage.clear();
//props.navigation.navigate('Home')
}},
],
{ cancelable: false }
)
} />
</DrawerContentScrollView>
);
}
下面提到了我的route.js。
export default function Routes(username, password) {
// eslint-disable-next-line no-shadow
const Stack = createStackNavigator();
const [loader, setloader] = useState('');
const [state, dispatch] = React.useReducer(
(prevState, action) => {
switch (action.type) {
case 'RESTORE_TOKEN':
return {
...prevState,
userToken: action.token,
isLoading: false,
};
case 'SIGN_IN':
return {
...prevState,
isSignout: false,
userToken: action.token,
};
case 'SIGN_OUT':
return {
...prevState,
isSignout: true,
userToken: undefined,
};
}
},
{
isLoading: true,
isSignout: false,
userToken: null,
},
);
React.useEffect(() => {
// Fetch the token from storage then navigate to our appropriate place
const bootstrapAsync = async () => {
let userToken;
try {
userToken = await AsyncStorage.getItem('@kiklee-user-id');
} catch (e) {
// Restoring token failed
}
// After restoring token, we may need to validate it in production apps
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
dispatch({type: 'RESTORE_TOKEN', token: userToken});
};
bootstrapAsync();
}, []);
const authContext = React.useMemo(
() => ({
signIn: async data => {
try {
let config_api_url = Config.api_login_url;
if (data.username === '' && data.password === '') {
Alert.alert(
'Error : ',
'Please enter your email address and password.',
);
} else if (data.username === '') {
Alert.alert('Error : ', 'Please enter your email address.');
} else if (
!(data.username === '') &&
Validate.isEmailValid(data.username) === true
) {
Alert.alert('Error : ', 'Please enter the correct email address.');
} else if (password.length < 5) {
Alert.alert(
'Error : ',
'Please enter your password with a minimum length of 5.',
);
} else {
// seterror(''); //empty all errors
setloader(true);
await fetch(config_api_url, {
method: 'POST',
body: JSON.stringify({
username: data.username,
password: data.password,
}),
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
})
.then(response => response.text())
.then(async responseData => {
// parse the json values
var responsevalue = JSON.parse(responseData);
if (responsevalue.login_status === 'Active') {
await AsyncStorage.removeItem('@kiklee-user-id');
await AsyncStorage.setItem(
'@kiklee-user-id',
responsevalue.id.toString(),
);
// const value = await AsyncStorage.getItem('@kiklee-user-id');
dispatch({type: 'SIGN_IN', token: 'dummy-auth-token'});
setloader(false);
// eslint-disable-next-line eqeqeq
} else if (responsevalue.login_status == 'Deactive') {
Alert.alert('Error : ', 'Userid is deactive.');
setloader(false);
} else {
Alert.alert('Error : ', 'Invalid username or password.');
setloader(false);
}
})
.catch(err => {
Alert.alert(err);
});
}
} catch (e) {
// saving error
Alert.alert('Please try your login after some time.');
}
},
signOut: async () => {
AsyncStorage.removeItem('@kiklee-user-id');
dispatch({type: 'SIGN_OUT'});
},
signUp: async data => {
dispatch({type: 'SIGN_IN', token: 'dummy-auth-token'});
},
}),
[],
);
if (state.isLoading) {
// We haven't finished checking for the token yet
return <SplashScreen />;
}
// Loader
if (loader == true) {
return (
<View style={styles.container}>
<Spinner
visible={true}
textContent={'Loading...'}
textStyle={styles.spinnerTextStyle}
/>
</View>
);
}
return (
<AuthContext.Provider value={authContext}>
<NavigationContainer>
{state.userToken == null ? (
<>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerShown: false,
animationTypeForReplace: state.isSignout ? 'pop' : 'push',
}}
/>
<Stack.Screen
name="Privacy"
component={Privacy}
options={{headerShown: false}}
/>
<Stack.Screen
name="ForgetPassword"
component={ForgetPassword}
options={{headerShown: true}}
/>
<Stack.Screen
name="SignUp"
component={Signup}
options={{headerShown: false}}
/>
</Stack.Navigator>
</>
) : (
<>
<Drawer.Navigator
initialRouteName="Dashboard"
drawerContent={props => CustomDrawerContent(props)}>
<Drawer.Screen name="Dashboard" component={MainRoot} />
</Drawer.Navigator>
</>
)}
</NavigationContainer>
</AuthContext.Provider>
);
}
我可以在自定义抽屉中调用authcontext,因为它将显示一个称为“挂钩规则”的错误
我仅在反应导航5上寻求帮助。
答案 0 :(得分:0)
尝试在const Stack = createStackNavigator();
组件上方定义Routes
。
您的useState
和useReducer
挂钩必须排在最前面。
答案 1 :(得分:0)
我遇到了同样的问题,但是最终我创建了一个解决方案,因为我尝试从不同的根源传递该功能作为道具,并且当我从客户抽屉项中记录道具时,它是不确定的...导致我进入我之前在React Navigation v4中使用过的解决方案。
解决方案:
创建自己的登出组件以及链接等其他功能。
const DrawerMeta = () => {
const { signOut } = useContext(AuthContext);
return (
<View style={{ flex: 1, justifyContent: "flex-end" }}>
<Button
onPress={async () => {
await signOut();
}}
title="sign out"
/>
</View>
);
};
插入抽屉组件
function CustomDrawerContent(props) {
//
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerMeta />
</DrawerContentScrollView>
);
}