繁体   English   中英

来自 AsyncStorage 更改的 React Native 触发器 useEffect

[英]React Native trigger useEffect from changes in AsyncStorage

所以我正在开发一个反应本机身份验证屏幕。 我将令牌存储在 AsyncStorage 中(是的,我知道这不是最好的解决方案)。 所以发生的事情是当我登录时,令牌被存储,但我的 Authentication.js 屏幕上的 getItem 没有被触发,并且配置文件屏幕没有被调用。 如果我登录然后手动刷新应用程序,我将被重定向到个人资料屏幕。

登录.js

function Login({navigation}) {
  const [signIn, {data}] = useMutation(USER_SIGNIN_MUTATION);
  const [userName, setUserName] = useState('');
  const [password, setPassword] = useState('');

  function handleLogIn() {
    signIn({
      variables: {
        email: userName,
        password: password,
      },
    });
  }

  useEffect(() => {
    if (data != null) {
      setToken();
    }
  });

  const setToken = async () => {
    try {
      console.log('before');
      await AsyncStorage.setItem('token', data.signIn.token);
      console.log('after');
    } catch (error) {
      console.log(error);
    }
  };
  return(
     ...
  )
}

身份验证.js

function Authentication() {
  const [localToken, setLocalToken] = useState(false);

  useEffect(() => {
    const fetchUser = async () => {
      try {
        console.log('before get');
        const userData = await AsyncStorage.getItem('token');
        if (userData !== null) {
          setLocalToken(true);
        }
      } catch (error) {
        console.log(error);
      }
    };
    fetchUser();
  }, [localToken]);

  console.log(`auth screen - ${localToken}`);
  return (
    <NavigationContainer>
      {localToken === true ? <ProfileStack /> : <AuthStack />}
    </NavigationContainer>
  );
}

export default Authentication;

注销 function 时也会发生同样的情况。 (function 运行,但我需要刷新应用程序才能返回登录屏幕)

Profile.js

function Profile({navigation}) {
  function signOut() {
    logOut();
  }

  const logOut = async () => {
    try {
      console.log('before clear');
      await AsyncStorage.removeItem('token');
      console.log('after clear');
    } catch (error) {
      console.log(error);
    }
  };
  return (
    ...
  )
}

我很感激对此的任何见解。

useEffect(() => {
    const fetchUser = async () => {
      try {
        console.log('before get');
        const userData = await AsyncStorage.getItem('token');
        if (userData !== null) {
          setLocalToken(true);
        }
      } catch (error) {
        console.log(error);
      }
    };
    fetchUser();
  }, [localToken]);

在这里,您在 useEffect 的依赖数组中添加了 localToken 变量。 所以你基本上是在说:只有当 localToken 变量发生变化时才运行这个效果。 但是你只能从效果中改变它。 所以尝试删除它并将依赖项保持为[]。 这样,效果将在组件渲染时运行。

关于您必须刷新页面这一事实,重要的是要了解为什么会发生这种情况。

  <NavigationContainer>
      {localToken === true ? <ProfileStack /> : <AuthStack />}
    </NavigationContainer> 

在这里,您将根据 localToken 值呈现 ProfileStack 或 AuthStack。 注销时,您会从 AsyncStorage 中删除令牌,但这还不够。 您实际上需要在 Authentication 组件中触发重新渲染,以便重新评估 localToken。 基本上,当您注销时,您还需要设置 setLocalToken(false)。 因此,您需要从 Profile 组件访问 setLocalToken function。 您可以将此 function 作为道具传递,或者更好地使用上下文 API

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM