javascript React Native -注销-无法执行React状态更新

olhwl3o2  于 2023-03-11  发布在  Java
关注(0)|答案(1)|浏览(113)

事实上,我正在开发一个移动应用程序,每天我都会发现一些关于React的新实践(我是初级),今天我需要关于一个功能的帮助:用户注销。
我的Logout函数位于Profil.js中的IconButton内,当按下时,将调用我的函数Logout
Profil.js

const Loggout = () => {
        AsyncStorage.setItem("@LoggedIn", "false");

        ToastMsgNotification.CustomSuccess("Déconnexion", "Vous avez été déconnecté")
        route.params.refreshApp()
    }

我的问题是在App.js后的路线.params.refreshApp(工程)!
App.js

async function CheckingSession() {
    let UserLoggedIn = await AsyncStorage.getItem("@LoggedIn");

    return UserLoggedIn;
}

async function CheckingAuth() {
    let UserToken = await AsyncStorage.getItem('@JWT')
    let UserLoggedIn = await AsyncStorage.getItem('@LoggedIn');

    if (UserLoggedIn != "true" && UserToken == null)
        return false;

    if (UserToken)
    { 
        let checkUserToken = await axiosInstance.post('/api/login/check_jwt', UserToken, {
            headers: {
                'Authorization': UserToken,
                'Accept' : 'application/json',
                'Content-Type': 'application/json'
            }
        }).then((answer) => {
            return answer.data.JWT;
        });

        if (checkUserToken == "OK")
            return true;
        
        ToastMsgNotification.CustomError("Accès expiré", "Merci de vous reconnecter à votre compte");

        return false;
    }
}

export default function App(props) {
    const [refreshPage, setRefreshPage] = React.useState(0);
    const [loaded] = useFonts({
        MontserratM: require('../../../assets/fonts/Montserrat-Medium.ttf'),
        MontserratB: require('../../../assets/fonts/Montserrat-Bold.ttf'),
        MontserratSB: require('../../../assets/fonts/Montserrat-SemiBold.ttf'),
        MontserratR: require('../../../assets/fonts/Montserrat-Regular.ttf'),
        MontserratL: require('../../../assets/fonts/Montserrat-Light.ttf'),
        MontserratXB: require('../../../assets/fonts/Montserrat-ExtraBold.ttf'),
    });
    const ref = React.useRef(null);
    const [userLoggedIn, setUserLoggedIn] = React.useState(false);
    const isMounted = React.useRef(true);

    useEffect(() => {
        const fetchData = async () => {
            return await CheckingAuth()
        }

        fetchData().then(r => (isMounted.current) ? setRefreshPage(refreshPage + 1) : '')

        const fetchSession = async () => {
            return await CheckingSession()
        }

        fetchSession().then((r) => { 
            setUserLoggedIn(r)
        })
    }, [])

    if (!loaded) {
        return null;
    }

    CheckingSession().then((r) => {
        setUserLoggedIn(r)
    })

    return (
        <NavigationContainer ref={ref}>
            <StatusBar style="dark" />
            { userLoggedIn == "true" ? 
                (<NavigationLoggedIn refreshApp={() => setRefreshPage(refreshPage + 1)} />) :
                (<NavigationNotLoggedIn refreshApp={() => setRefreshPage(refreshPage + 1)} />)
            }
            <Toast config={toastConfig} style={{position: 'absolute'}}/>
        </NavigationContainer>
    )
}

我理解问题来源为:检查会话()中设置用户登录(r)。如果(!已加载),则在之后设置()
但我真的不知道如何修复错误:警告:无法对已卸载的组件执行React状态更新。这是一个无操作,但它指示应用程序中存在内存泄漏。若要修复,请取消% s中的所有订阅和异步任务。%s是SvgUri中的useEffect清理函数...........
如果有人能帮我,谢谢!
我尝试过abortController、useIsMounted,但我真的不明白...我尝试过在Profil.js中添加UseEffect,但也产生了错误

nkhmeac6

nkhmeac61#

这不是问题的直接答案,但是使用Context会使事情变得简单,上下文提供了一种通过组件树传递登录状态的方法。
这是一个最小的例子。

const AuthContext = createContext()

function Toolbar({login}) {
  const {loggedIn} = useContext(AuthContext)
  return <Button title={loggedIn ? "Logout": "Login"} onPress={login}/>
}

function Content() {
  const {loggedIn} = useContext(AuthContext)
  return <>
    { loggedIn ? <Text>User is logged in</Text> : <Text>Please log in</Text> }
  </>
}

function Screen() {
  const {loggedIn, setLoggedIn} = useContext(AuthContext)
  return <>
    <Toolbar login={() => setLoggedIn(!loggedIn)} />
    <Content/>
  </>
}

function App() {
  const [loggedIn, setLoggedIn] = useState(false)
  useEffect(() =>  {
    const getLoggedIn = async () => {
      const loggedIn = JSON.parse(await AsyncStorage.getItem('loggedIn'))
      setLoggedIn(loggedIn)
    }
    getLoggedIn()
  }, [])

  return <AuthContext.Provider value={{
      loggedIn,
      setLoggedIn: (value) => {
        AsyncStorage.setItem("loggedIn", JSON.stringify(value))
        setLoggedIn(value)
      },
    }}>
    <Screen/>
  </AuthContext.Provider>
}

export default App

请参阅AuthFlow了解更详细的信息。

相关问题