React Native在Redux中使用自定义钩子

y0u0uwnf  于 2023-10-19  发布在  React
关注(0)|答案(1)|浏览(136)

我已经使用React Native很多年了,但我现在正在学习一些我以前没有使用过的概念。
我目前正在学习Redux,并将其集成到React Native中。我正在学习的课程是使用Redux来管理Facebook的身份验证。然而,我没有计划在我可预见的任何应用程序中使用Facebook Auth,而是Google。
我现有的一个应用程序,使用了一个自定义钩子,在那里我处理Google Sign In,但这是直接在我需要的组件中调用的,我将令牌存储在上下文中。我知道钩子只能在函数组件的主体中调用,我正在努力让它在Redux中工作。
我已经设置了我的减速器和商店,并正在对行动本身的工作。
我的Google自定义钩子看起来像这样:

import * as Google from 'expo-auth-session/providers/google';
import { useEffect, useState } from 'react';

const useGoogleSignIn = () => {
  const useProxy = __DEV__ ? true : false
  const [request, response, promptAsync] = Google.useAuthRequest({
    androidClientId: '',
    iosClientId: '',
    expoClientId: '',
  });
  const [accessToken, setAccessToken] = useState();

  useEffect(() => {
    if (response?.type === 'success') {
      setAccessToken(response.authentication.accessToken);
    }
  }, [response]);

  const promptMobileGoogleSignIn = () => promptAsync({ useProxy, showInRecents: true });
  const isGoogleClientAvailable = !!request;

  return {
    response,
    accessToken,
    isGoogleClientAvailable,
    promptMobileGoogleSignIn,
  };
};

export default useGoogleSignIn;

我的行动

import AsyncStorage from '@react-native-async-storage/async-storage';
import { GOOGLE_LOGIN_SUCCESS, GOOGLE_LOGIN_FAIL } from './types';

export const googleLogin = () => async (dispatch) => {
  const token = await AsyncStorage.getItem('google_token');

  if (token) {
    // User has completed Google Login
    dispatch({ type: GOOGLE_LOGIN_SUCCESS, payload: token });
  } else {
    const handleGoogleLogin(dispatch)
  }
};

const handleGoogleLogin = async dispatch => {
  // Handle the sign in, and get the accessToken
  const response = ...
  if (response?.type === 'success') {
    await AsyncStorage.setItem('google_token', response.authentication.accessToken);
    dispatch({ type: GOOGLE_LOGIN_SUCCESS, payload: response.authentication.accessToken });
  } else if (response?.type === 'cancel') {
    return dispatch({ type: GOOGLE_LOGIN_FAIL });
  }
}

就像我提到的,我是Redux的新手,所以我为任何错误道歉。

66bbxpm5

66bbxpm51#

我设法找到了解决上述问题的方法。我仍然没有完全了解Redux,还没有看到和欣赏它的好处。但是,我改变了以前使用的登录Google的方法,使用了较新的@react-native-google-signin/google-signin而不是expo-auth-session/providers/google
目前,我的实现非常小,但我删除了我创建的自定义钩子,现在我的操作如下所示:

import AsyncStorage from '@react-native-async-storage/async-storage';
import { GOOGLE_LOGIN_SUCCESS, GOOGLE_LOGIN_FAIL } from './types';
import { GoogleSignin, statusCodes } from '@react-native-google-signin/google-signin';
import Constants from 'expo-constants';

export const googleLogin = () => async (dispatch) => {
  const token = await AsyncStorage.getItem('google_token');

  if (token) {
    dispatch({ type: GOOGLE_LOGIN_SUCCESS, payload: token });
  } else {
    handleGoogleLogin(dispatch);
  }
};

const handleGoogleLogin = async (dispatch) => {
  GoogleSignin.configure({
    androidClientId: Constants.expoConfig.extra.googleAndroidClientId,
    iosClientId: Constants.expoConfig.extra.googleiOSClientId,
  });
  try {
    await GoogleSignin.hasPlayServices();
    await GoogleSignin.signIn();
    const { accessToken } = await GoogleSignin.getTokens();
    if (accessToken) {
      await AsyncStorage.setItem('google_token', accessToken);
      dispatch({ type: GOOGLE_LOGIN_SUCCESS, payload: accessToken });
    } else {
      return dispatch({ type: GOOGLE_LOGIN_FAIL });
    }
  } catch (error) {
    if (error.code === statusCodes.SIGN_IN_CANCELLED) {
      // user cancelled the login flow
      console.log('User cancelled the login flow');
    } else if (error.code === statusCodes.IN_PROGRESS) {
      // operation (e.g. sign in) is in progress already
      console.log('Operation is in progress');
    } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
      // play services not available or outdated
      console.log('Service not available');
    } else {
      // some other error happened
      console.log(error);
    }
    return dispatch({ type: GOOGLE_LOGIN_FAIL });
  }
};

相关问题