[英]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
)
}
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.我看到了将结果存储在 AsyncStorage 中的代码,然后,第一次安装组件时,它会检查结果是否为真,并显示屏幕。 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.
如果您正在使用快速刷新并更新代码,则 useEffect 将不会再次运行,因为屏幕已经挂载并且您有一个空的依赖项数组。
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.
我没有看到任何用于注销用户或清除 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:
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.您已经在顶级 useEffect 中使用此模式来破坏您的语音识别器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.