'why i have to refresh/rewrite my code to make it work while trying to save the state for a specific user in react native
I am trying to make a test sheet for user. If he passes the test, he is directed to a pass screen and even after totally closing the app, when that specific user comes back, the state is saved meaning, the passing screen still remains there. But for a new user, I want the app to run from start and show him test screen 1st and then act accordingly if he passes the test or not. My app is working fine but it keeps reacting according to the user that was previously logged in, until i refresh/rewrite any of the lines from code. Then it acts correctly according to the current user. Following is the code:
import React ,{useState, useEffect} from "react";
import {View, Alert, Image, StyleSheet, Text, Modal, TouchableOpacity, TouchableHighlight} from 'react-native';
import Voice from 'react-native-voice';
import auth from '@react-native-firebase/auth';
import AsyncStorage from '@react-native-async-storage/async-storage';
const key = auth().currentUser.uid + "hasPassed"
export const hasPassed = async () => {
return AsyncStorage.getItem(key).then(result => result != null ? JSON.parse(result) : undefined).catch(e => console.log(e))
}
export const setHasPassed = async (newPassed) => {
return AsyncStorage.setItem(key, JSON.stringify({hasPassed: newPassed})).catch(e => console.log(e))
}
export default alpht =({navigation}) => {
const [index, setind] = useState(0);
const [idis, setidis] = useState(false);
const [count, setcount] = useState(0);
const [error, setError] = useState('');
const [results, setResults] = useState('');
const [disb, setdis] = useState(true);
const [ndisb, setndis] = useState(true);
useEffect(() => {
//Setting callbacks for the process status
Voice.onSpeechStart = onSpeechStart;
Voice.onSpeechEnd = onSpeechEnd;
Voice.onSpeechResults = onSpeechResults;
Voice.onSpeechError = onSpeechError;
return () => {
//destroy the process after switching the screen
Voice.destroy().then(Voice.removeAllListeners);
};
}, []);
const onSpeechStart = (e) => {
//Invoked when .start() is called without error
console.log('onSpeechStart: ', e);
};
const onSpeechEnd = (e) => {
console.log('onSpeechEnd: ', e);
setdis(false);
setndis(true);
//Invoked when SpeechRecognizer stops recognition
};
const onSpeechError = (e) => {
//Invoked when an error occurs.
console.log('onSpeechError: ', e);
setError(JSON.stringify(e.error));
};
const onSpeechResults = (e) => {
//Invoked when any results are computed
console.log('onSpeechResults: ', e);
setResults(e.value);
};
const startRecognizing = async () => {
//Starts listening for speech for a specific locale
try {
await Voice.start('tr-TURKEY');
setError('');
setResults('');
} catch (e) {
//eslint-disable-next-line
console.error(e);
}
};
const destroyRecognizer = async () => {
//Destroys the current SpeechRecognizer instance
try {
await Voice.destroy();
setError('');
setResults('');
setdis(true);
if (index<7){
setind(index+1);
setndis(true);
setidis(false);
}
// console.log(index);
// if (index==6){
// setndis(true);
// }
} catch (e) {
//eslint-disable-next-line
console.error(e);
}
};
function Check() {
if (results.includes(words[index])){
Alert.alert('Correct!','You are learning so well!');
if(index==7) {
if(count<=5)
{
setHasPassed(true).then(() => setshowpass(true))
//setshowpass(true);
}
else{
console.log(count)
Alert.alert('fail','fail');
}
}
if (index==7){
setndis(true);
setdis(true);
setidis(true);
}
else{
setndis(false);
setdis(true);
setidis(true);
}
}
else{
Alert.alert('Ops!','Looks like you went wrong somewhere. Try again!');
setcount(count+1);
setdis(true);
setndis(true);
if(count==5){
Alert.alert('Restest', 'Looks like you had way too many mistakes!')
setind(0);
setcount(0);
setdis(true);
}
}
}
const words=['ceket', 'çilek', 'elma', 'fare', 'öğretmen', 'otobüs', 'şemsiye', 'uçak'];
const [show, setshow]=useState('');
const [showpass, setshowpass]=useState(false);
useEffect(() => {
//console.log(auth().currentUser.uid);
setshow(true);
}, []);
useEffect(() => {
const getState = async () => {
const result = await hasPassed()
setshowpass(result ? result.hasPassed : false)
}
getState()
// console.log(auth().currentUser.uid)
// if (showpass === false) {
// setshow(true)
// console.log('hey');
// // return null
// }
}, []);
console.log(auth().currentUser.uid)
if (showpass === false) {
// setshow(true)
console.log('hey');
return null
}
return(
...
// all the other code here
)
}
Solution 1:[1]
I see code to store the result in AsyncStorage, and then, the first time the component mounts, it checks whether the result is true, and shows the screen. If you're using fast refresh, and you update the code, the useEffect won't run again, since the screen has already mounted and you have an empty dependency array.
So, to me, it looks like you've built it to produce the behavior you've described. I don't see any code to log a user out or to clear AsyncStorage. Maybe there is some mechanism you haven't shown to do that. If not, one way to accomplish this is in the return of the useEffect:
useEffect(() => {
...
return () => {
setHasPassed(undefined).then(() => logOut());
// not sure how you log out your user
You're already using this pattern in your top useEffect to destroy your speech recognizer.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Abe |