I am trying to authenticate a user using biometrics and pin on my app and I am trying to pass states to the PinSreen. But I am getting an error
Invalid attempt to destructure non-iterable instance. In order to be iterable, non-array objects must have a Symbol.iteratormethod.
Here is my APP.js
import { AuthContext } from './contexts/AuthContext';
const Stack = createStackNavigator();
const theme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: "transparent",
},
};
const App = () => {
const [onboarded, setOnboarded] = useState(false);
const [authenticated, setAuthenticated] = useState(false);
useEffect(() => {
getStorage();
}, []);
const getStorage = async () => {
const onboarded = await AsyncStorage.getItem('@onboarded');
setOnboarded(JSON.parse(onboarded));
};
const [loaded] = useFonts({
SFBold: require("./assets/fonts/sf-bold.ttf"),
SFMedium: require("./assets/fonts/sf-medium.ttf"),
SFRegular: require("./assets/fonts/sf-regular.ttf"),
SFLight: require("./assets/fonts/sf-light.ttf"),
});
if (!loaded) return null;
return (
<AuthContext.Provider value={{ authenticated, setAuthenticated }}>
<NavigationContainer theme={theme} >
<Stack.Navigator initialRouteName={!onboarded ? 'Onboarding' : !authenticated ? 'PinScreen' : 'BottomBar'} screenOptions={{ headerShown: false }}>
<Stack.Screen name="BottomBar" component={BottomBar} />
<Stack.Screen name="PinScreen" component={PinScreen} />
<Stack.Screen name="Onboarding" component={Onboarding} />
<Stack.Screen name="CodeScanner" component={CodeScanner} />
<Stack.Screen name="SignUp" component={SignUp} />
<Stack.Screen name="SignIn" component={SignIn} />
<Stack.Group screenOptions={{ presentation: 'modal' }}>
<Stack.Screen name="Deposit" component={Deposit} />
<Stack.Screen name="Authorise" component={Authorise} />
</Stack.Group>
</Stack.Navigator>
</NavigationContainer>
</AuthContext.Provider>
);
}
export default App;
And here is my PinScreen where after the pin biometrics are input correctly, the setAuthenticated(true);
is set
const PinScreen = () => {
const navigation = useNavigation();
const [pin, setPin] = useState('');
const [authenticated, setAuthenticated] = useContext(AuthContext);
const [isBiometricSupported, setIsBiometricSupported] = useState(false);
const [isPinSet, setIsPinSet] = useState(false);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
useEffect(() => {
(async () => {
const compatible = await LocalAuthentication.hasHardwareAsync();
setIsBiometricSupported(compatible);
})();
});
const handleButtonPress = (value) => {
if (pin.length < 6) {
setPin(pin value);
}
}
function onAuthenticate() {
LocalAuthentication.authenticateAsync().then(auth => {
if (auth.success) {
setAuthenticated(true);
setLoading(true);
setTimeout(() => {
navigation.navigate('BottomBar', { screen: 'Home' });
}, 800);
} else {
setError(true);
Vibration.vibrate(200);
}
});
}
Why am I getting the error. Why is it not working? Please help
CodePudding user response:
When you're passing the authenticated
and setAuthenticated
to your AuthContext.Provider
, you pass it as a object {}
.
<AuthContext.Provider value={{ authenticated, setAuthenticated }}>
Then in your PinScreen
you try to desctructure it as a array []
const [authenticated, setAuthenticated] = useContext(AuthContext);
Instead you should destructure it as a object
const { authenticated, setAuthenticated } = useContext(AuthContext);
CodePudding user response:
Your error seems to be here in PinScreen.js:
const [authenticated, setAuthenticated] = useContext(AuthContext);
You are trying to destructure an array that is actually an object.:
<AuthContext.Provider value={{ signed: true, Login }}>
Try the following change in PinScreen.js:
const { authenticated, setAuthenticated } = useContext(AuthContext);