로그인 파트 정리

1. UseInput

2. email Regex

2-1. emailRegex.test()

2-2. TouchableWithoutFeedback

keyboard.dismiss

3. requestSecret Mutation

3-1. emailValvue.value 실수

const requestSecretMutation = useMutation(LOG_IN, {
    variables: {
      email: emailValue.value
    }
  });

3-2. onSubmitEditing

4. react-apollo-hooks UseMutation

useMutation을 사용할 때 공식사이트에서 알려주는 방식이 예전과 조금 달라진 것 같습니다.

1564419809391

1564419821063

위와 같이 useMutation[addTask]에 넣습니다. 예전 버전으로 작성한 코드를 보면 아래와 같이 Mutation을 함수처럼 사용합니다. 하지만 현재 버전에서는 [function,{loading ...}]처럼 fuction설정값을 가지고 있는 object로 return되기 때문에 아래와 같이 사용할 경우 addTask는 function이 아니라는 에러를 띄우게 됩니다.

const addTask = useMutation(ADD_TASK_MUTATION, {
    variables: {
      text: inputRef.current.value,
    },
  });

해결 방법

Login.js

const [requestSecretMutation] = useMutation(LOG_IN, {
    variables: {
      email: emailValue.value
    }
  });

위와 같이 배열형태의 requestSecretMutation를 받게 되면 나머지 속성들은 받지 않고 function만 사용한다는 의미입니다. 그래서 requestSecretMutation을 콘솔에 찍어보면

[Function anonymous]라고 나오게 됩니다. function을 사용하는 방법을 알았다면, 호출만 하면됩니다.

5. 안드로이드에서 서버에 데이터 요청하기

호출을 할 때 제가 생각하기로 prisma서버가 localhost:4000에 열어 놨기 때문에 아래와 같이 클라이언트를 만들때 속성을 localhost로 주어야 한다고 생각했습니다.

apollo.js

const apolloClientOptions = {
  uri: "http://localhost:4000"
};

export default apolloClientOptions;

하지만 안드로이드의 경우 개발환경의 경우에도 local이 아닌 ip주소를 입력해서 호출해야한다고 합니다.

해결방법

아래와 같이 아이피 주소를 넣은 uri를 만들어주면 됩니다.

apollo.js

const apolloClientOptions = {
  uri: "http://ip주소:4000"
};

export default apolloClientOptions;

근데 여기서 스마트폰을 직접 사용할 경우 동작하지 않았고,,,, 안드로이드 스튜디오의 에뮬레이터를 사용해서 expo를 실행했을 경우에 서버에서 데이터를 가져오는 부분이 제대로 동작했습니다. 이 부분은 아직 정확히 이해가 가지 않았고, 왜 스마트폰 환경에서는 동작하지 않는 것이 에뮬레이터 환경에서는 동작하는지 알아봐야 할 것 같습니다.

1564420706501

위와 같이 useMutation과 ip에 대한 이슈를 해결하고 나면 로그인에 필요한 인증키 전송에 성공했다는 알림을 받을 수 있었습니다…..


6. ConfirmSecret

  • 화면 형식은 login화면과 동일.

    1564480304597

  • 이메일**은 로그인 창에서 navigation에서 params으로 넘겨줘야 한다.
  • Confirm을 누르면 이메일,인증키 Mutation을 요청해서 jwt를 return 받기

  • return 받은 jwtAsyncStorage에 넣는다.

  • AuthContextisLoggedIn을 true로 해줘서 rerender를 해서 MainNavigation으로 이동한다. (NavigationController.js참고)

    useLogIn사용할 떄 주의하기

    //NavigationController.js
      
    export default () => {
      const { isLoggedIn } = useContext(AuthContext);
      return (
        <View style=>
          {isLoggedIn ? <MainNavigation /> : <AuthNavigation />}
        </View>
      );
    };
    

    MainNavigation으로 이동하면 TabNavigation으로 이동한다.

    //MainNavigation.js
      
    import { createStackNavigator, createAppContainer } from "react-navigation";
    import TabNavigation from "./TabNavigation";
    import PhotoNavigation from "./PhotoNavigation";
    import MessagesNavigation from "./MessagesNavigation";
    const MainNavigation = createStackNavigator(
      {
        TabNavigation,
        PhotoNavigation,
        MessagesNavigation
      },
      {
        headerMode: "none"
      }
    );
      
    export default createAppContainer(MainNavigation);
      
    

앱 시작시 로그인 여부 판단 방법

1. AsyncStorage에서 데이터 확인

App.js

//check islogin
      const isLoggedIn = await AsyncStorage.getItem("isLoggedIn");
      console.log("isLoggedIn", isLoggedIn);
      if (isLoggedIn === "null" || isLoggedIn === "false") {
        setIsLoggedIn(false);
      } else {
        setIsLoggedIn(true);
      }

2. AuthProvider에게 isLoggedIn넘겨주기

App.js

return loaded && client && isLoggedIn !== null ? (
    <ApolloProvider client={client}>
      <ThemeProvider theme={Theme}>
        <AuthProvider isLoggedInProp={isLoggedIn}>
          <NavContainer />
        </AuthProvider>
      </ThemeProvider>
    </ApolloProvider>
  ) : (
    <AppLoading />
  );

3. AuthProvider에서는 받은 데이터로 초기 state 셋팅


export const AuthProvider = ({ isLoggedInProp, children }) => {
  
  const [isLoggedIn, setIsLoggedIn] = useState(isLoggedInProp); 
  
  (...중략...)
};

App.js에서 넘겨준 isLoggedIn으로 초기화 시킴. 이 stateNavController를 통해서 첫 화면을 결정시켜줌! setState를 하게 되면 reRender를 하기 때문에 다시 그려짐.

NavController.js

import React from "react";
import { View, Text, TouchableOpacity } from "react-native";
import { useIsLoggedId } from "../AuthContext";
import AuthNavigation from "../navigation/AuthNavigation";
import MainNavigation from "../navigation/MainNavigation";

export default () => {
  const isLoggedIn = useIsLoggedId();
  console.log(isLoggedIn);
  // const { logUserOut } = useContext(AuthContext);
  // const { logUserIn } = useContext(AuthContext);
  return (
    <View style=>
      {isLoggedIn ? <MainNavigation /> : <AuthNavigation />}
    </View>
  );
};

여기서도 아래와 같이 객체에 담는 것이 아니라

const {isLoggedIn} = useIsLoggedIn();

변수에 isLoggedIn을 담는 것이니 아래와 같이 작성하면 됩니다.

const isLoggedIn = useIsLoggedIn();