我是第一次使用原生react ,我想访问useFocusEffect中变量的更新状态,目前在Start const[记住,setRemember]=useState()时声明的常量没有更新,我正在useFocusEffec.中使用它.对此有什么 idea 吗?

  const rememberMe = ({ navigation }) => {
  const [remember, setRemember] = useState();

  useEffect(() => {
    getUserEmailAndPassword();
  }, []);

  const getUserEmailAndPassword = async () => {
    try {
      const loginSaved = await AsyncStorage.getItem("userLoginDetails");
      const currentUser = JSON.parse(loginSaved);
      if (currentUser?.state == true) {
        setRemember(true);
      } else {
        setRemember(false);
      }
    } catch (error) {}
  };

  useFocusEffect(
    useCallback(() => {
      return () => {
       // here remember is not updating 
        if (remember === true) {
          forgetUser();
        } else {
          try {
            const loginSaved = AsyncStorage.getItem("userLoginDetails");
            const currentUser = JSON.parse(loginSaved);
            if (
              currentUser?.userEmail !== null &&
              currentUser?.userPassword != null
            ) {
              rememberUser(
                currentUser?.userEmail,
                currentUser?.userPassword,
                (state = true)
              );
            }
          } catch (error) {}
        }
      };
    }, [])
  );

  const rememberUser = async (email, password, state) => {
    const userLoginDetails = {
      userEmail: email,
      userPassword: password,
      state: state,
    };
    try {
      await AsyncStorage.setItem(
        "userLoginDetails",
        JSON.stringify(userLoginDetails)
      );
    } catch (error) {
      // Error saving data
    }
  };

  const checkToRemember = (value) => {
    if (value == true) {
      setRemember(false);
    } else {
      setRemember(true);
    }
  };

  const forgetUser = async () => {
    try {
      await AsyncStorage.removeItem("userLoginDetails");
    } catch (error) {
      // Error removing
    }
  };

  return (
    <SafeAreaView
      style={styles.securityContainer}
      edges={["right", "top", "left"]}
    >
      <Toggle
        isOn={remember}
        onToggle={() => {
          setRemember(!remember);
          checkToRemember(remember);
        }}
      />
    </SafeAreaView>
  );
};

export default rememberMe;

当焦点被移走时,获得未定义的记忆值,它不会更新.

推荐答案

您面临的问题是,useFocusEffect回调仅在组件挂载时创建一次,并且它捕获当时未定义的记住状态变量的初始值.即使稍后更新了记忆状态,捕获的值也保持不变.

要在useFocusEffect回调中访问更新后的状态值,可以使用ref保存对记住状态的引用.以下是您的代码的更新版本,其中包括此修改:

import React, { useState, useEffect, useCallback, useRef } from 'react';
import { SafeAreaView, AsyncStorage } from 'react-native';
import { useFocusEffect } from '@react-navigation/native';
import Toggle from './Toggle'; // assuming you have a Toggle component

const rememberMe = ({ navigation }) => {
  const [remember, setRemember] = useState();
  const rememberRef = useRef();

  useEffect(() => {
    getUserEmailAndPassword();
  }, []);

  useEffect(() => {
    rememberRef.current = remember;
  }, [remember]);

  useEffect(() => {
    if (rememberRef.current === true) {
      forgetUser();
    } else {
      try {
        const loginSaved = AsyncStorage.getItem("userLoginDetails");
        const currentUser = JSON.parse(loginSaved);
        if (
          currentUser?.userEmail !== null &&
          currentUser?.userPassword != null
        ) {
          rememberUser(
            currentUser?.userEmail,
            currentUser?.userPassword,
            (state = true)
          );
        }
      } catch (error) {}
    }
  }, []);

  const getUserEmailAndPassword = async () => {
    try {
      const loginSaved = await AsyncStorage.getItem("userLoginDetails");
      const currentUser = JSON.parse(loginSaved);
      if (currentUser?.state == true) {
        setRemember(true);
      } else {
        setRemember(false);
      }
    } catch (error) {}
  };

  useFocusEffect(
    useCallback(() => {
      return () => {
        if (rememberRef.current === true) {
          forgetUser();
        } else {
          try {
            const loginSaved = AsyncStorage.getItem("userLoginDetails");
            const currentUser = JSON.parse(loginSaved);
            if (
              currentUser?.userEmail !== null &&
              currentUser?.userPassword != null
            ) {
              rememberUser(
                currentUser?.userEmail,
                currentUser?.userPassword,
                (state = true)
              );
            }
          } catch (error) {}
        }
      };
    }, [])
  );

  const rememberUser = async (email, password, state) => {
    const userLoginDetails = {
      userEmail: email,
      userPassword: password,
      state: state,
    };
    try {
      await AsyncStorage.setItem(
        "userLoginDetails",
        JSON.stringify(userLoginDetails)
      );
    } catch (error) {
      // Error saving data
    }
  };

  const checkToRemember = (value) => {
    if (value == true) {
      setRemember(false);
    } else {
      setRemember(true);
    }
  };

  const forgetUser = async () => {
    try {
      await AsyncStorage.removeItem("userLoginDetails");
    } catch (error) {
      // Error removing
    }
  };

  return (
    <SafeAreaView
      style={styles.securityContainer}
      edges={["right", "top", "left"]}
    >
      <Toggle
        isOn={remember}
        onToggle={() => {
          setRemember(!remember);
          checkToRemember(remember);
        }}
      />
    </SafeAreaView>
  );
};

export default rememberMe;

在更新后的代码中,Memory Ref useRef挂钩用于创建一个可变的Ref,该引用包含对Memory状态变量的引用.每当记忆状态改变时,此引用都会更新.

在具有空依赖关系数组的useEffect钩子中,这相当于ComponentDidmount生命周期方法,通过将其赋给reemory Ref.Current来捕获emory的初始值.

在useFocusEffect回调中,当组件失go 焦点时,将判断reemory Ref.Current的值,而不是直接使用记住状态.因为ref是可变的,并且保存最新的值,所以即使在组件挂载时创建了回调,它也会反映更新的reemory的值.

这一修改允许您在useFocusEffect回调中访问更新后的状态值,以确保您使用的是正确的值.

Reactjs相关问答推荐

运行 node server.js会导致以下错误:Route.post()需要回调函数,但在Route.&处得到了[对象Undefined] lt;计算>

从app.js导航,这是在BrowserRouter包装之外

在React中映射对象数组时,如何正确呈现JSX.Element或React.ReactNode类型?

useRef()的钩子调用无效

我发送的 prop 的值不会改变.如果成功登录,导航栏中的 prop 必须为 true.我从后端得到 200 ok

当`useSelector`回调中的属性值更新时,将会使用更新后的值吗?

React Native 背景动画反转

MUI TextField Select 菜单的最大高度

如何在 ReactJS 中提交后删除 URL 中的查询参数

带有 webpack 错误多个文件匹配路由名称的 Expo-router.无法Bundle 或部署应用程序

使用 react-markdown 组件时 Tailwind CSS 的问题

添加新行时自动打开可扩展表格(Antd 表格,ReactJS)

如何通过onpress on view in react native flatlist来降低和增加特定视图的高度?

将 ref 赋予功能组件以使用内部功能

list 组件未按预期运行

将路径数组传递给Route会引发错误

使用输入类型文本对 useState 和日期做出react

无法重用我的组件,它只显示 1 次

服务器端分页未按预期工作

在渲染不显示子元素之后,再次渲染时,子元素状态数据完全消失了.为什么会这样以及如何防止它发生?