인프런 커뮤니티 질문&답변

qdial214님의 프로필 이미지
qdial214

작성한 질문수

배달앱 클론코딩 [with React Native]

회원가입 서버 연동 진행 중에 무한 로딩 현상이 발생합니다..

작성

·

782

0

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
 
주소가 잘못된 것 같기도 한데..
 
 
메트로 서버에 주소까지는 콘솔 잘 찍히구요 빌드 후안드로이드 스튜디오에서 10.0.2.2:3105 주소가 나오는 것 확인 했습니다..
 
public static final String API_URL = "http://10.0.2.2:3105";
 
어떤 문제 인지 알 수 있을까요..?
 
아래는 SignUp 코드 전문 입니다
import React, {useCallback, useRef, useState} from 'react';
import {
  ActivityIndicator,
  Alert,
  KeyboardAvoidingView,
  Platform,
  Pressable,
  StyleSheet,
  Text,
  TextInput,
  View,
} from 'react-native';
import {NativeStackScreenProps} from '@react-navigation/native-stack';
import {RootStackParamList} from '../../App';
import DismissKeyboardView from '../components/DismissKeyboardView';
import axios, { AxiosError } from 'axios';
import Config from 'react-native-config';

type SignUpScreenProps = NativeStackScreenProps<RootStackParamList, 'SignUp'>;

function SignUp({navigation}: SignUpScreenProps) {
  const [loading, setLoading] = useState(false);
  const [email, setEmail] = useState('');
  const [name, setName] = useState('');
  const [password, setPassword] = useState('');
  const emailRef = useRef<TextInput | null>(null);
  const nameRef = useRef<TextInput | null>(null);
  const passwordRef = useRef<TextInput | null>(null);

  const onChangeEmail = useCallback(text => {
    setEmail(text.trim());
  }, []);

  const onChangeName = useCallback(text => {
    setName(text.trim());
  }, []);

  const onChangePassword = useCallback(text => {
    setPassword(text.trim());
  }, []);
 
  const onSubmit = useCallback( async () => {
    if (loading) {
      return;
     } //로딩 중인데 버튼 누를 경우 요청 XX

    if (!email || !email.trim()) {
      return Alert.alert('알림', '이메일을 입력해주세요.');
    }

    if (!name || !name.trim()) {
      return Alert.alert('알림', '이름을 입력해주세요.');
    }

    if (!password || !password.trim()) {
      return Alert.alert('알림', '비밀번호를 입력해주세요.');
    }

    if (
      //이메일을 검사하는 정규 표현식
      !/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/.test(
        email,
      )
    ) {
      return Alert.alert('알림', '올바른 이메일 주소가 아닙니다.');
    }

    if (!/^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[$@^!%*#?&]).{8,50}$/.test(password)) {
      return Alert.alert(
        '알림',
        '비밀번호는 영문,숫자,특수문자($@^!%*#?&)를 모두 포함하여 8자 이상 입력해야합니다.',
      );
    }
    console.log(email, name, password);
    //axios 사용해서 서버로 보내주기, async await 문법 쓸거임
    try{
      setLoading(true);
      console.log(Config.API_URL);
      //Http 메서드 : get, put, patch, post, delete, head, options 등 (get, delete는 data를 못넣음)
      const response = await axios.post(`${Config.API_URL}/user`, {
        email,
        name,
        password,
      });// 네이버에 내 아이피 치면 내 주소 나옴

      console.log(response.data);
      Alert.alert('알림', '회원가입 되었습니다.');
      navigation.navigate('SignIn');
    } catch (error) {
      // 요청 실패 시
      const errorResponse = (error as AxiosError).response; //타입 적용한 변수
 
      console.error(errorResponse);
      if(errorResponse) {
        Alert.alert(errorResponse.data.message);
      }

    } finally {
      //try든 catch든 항상 최종적으로 finally 구문 실행함
      setLoading(false);
    }
  }, [loading, navigation, email, name, password]);

  const canGoNext = email && name && password;
  return (
    <KeyboardAvoidingView behavior = "position">
      <View style={styles.inputWrapper}>
        <Text style={styles.label}>이메일</Text>
        <TextInput
          style={styles.textInput}
          onChangeText={onChangeEmail}
          placeholder="이메일을 입력해주세요"
          placeholderTextColor="#666"
          textContentType="emailAddress"
          value={email}
          returnKeyType="next"
          clearButtonMode="while-editing"
          ref={emailRef}
          onSubmitEditing={() => nameRef.current?.focus()}
          blurOnSubmit={false}
        />
      </View>
      <View style={styles.inputWrapper}>
        <Text style={styles.label}>이름</Text>
        <TextInput
          style={styles.textInput}
          placeholder="이름을 입력해주세요."
          placeholderTextColor="#666"
          onChangeText={onChangeName}
          value={name}
          textContentType="name"
          returnKeyType="next"
          clearButtonMode="while-editing"
          ref={nameRef}
          onSubmitEditing={() => passwordRef.current?.focus()}
          blurOnSubmit={false}
        />
      </View>
      <View style={styles.inputWrapper}>
        <Text style={styles.label}>비밀번호</Text>
        <TextInput
          style={styles.textInput}
          placeholder="비밀번호를 입력해주세요(영문,숫자,특수문자)"
          placeholderTextColor="#666"
          onChangeText={onChangePassword}
          value={password}
          keyboardType={Platform.OS === 'android' ? 'default' : 'ascii-capable'}
          textContentType="password"
          secureTextEntry
          returnKeyType="send"
          clearButtonMode="while-editing"
          ref={passwordRef}
          onSubmitEditing={onSubmit}
        />
      </View>
      <View style={styles.buttonZone}>
        <Pressable
          style={
            canGoNext
              ? StyleSheet.compose(styles.loginButton, styles.loginButtonActive)
              : styles.loginButton
          }
          disabled={!canGoNext || loading} // || 로딩 중 일때는 회원가입 버튼 클릭 안되게
          onPress={onSubmit}>
         
          { loading ? (
          <ActivityIndicator color='white'/> // 로딩
          ) : (
            <Text style={styles.loginButtonText}>회원가입</Text>
          )}

        </Pressable>
      </View>
    </KeyboardAvoidingView>
  );
}

const styles = StyleSheet.create({
  textInput: {
    padding: 5,
    borderBottomWidth: StyleSheet.hairlineWidth,
  },
  inputWrapper: {
    padding: 20,
  },
  label: {
    fontWeight: 'bold',
    fontSize: 16,
    marginBottom: 20,
  },
  buttonZone: {
    alignItems: 'center',
  },
  loginButton: {
    backgroundColor: 'gray',
    paddingHorizontal: 20,
    paddingVertical: 10,
    borderRadius: 5,
    marginBottom: 10,
  },
  loginButtonActive: {
    backgroundColor: 'blue',
  },
  loginButtonText: {
    color: 'white',
    fontSize: 16,
  },
});

export default SignUp;

답변 2

0

.env 파일을 한 번 확인해보시기 바랍니다

( 띄어쓰기가 있으면 안되고, 내용이 틀리면 안됩니다.)

API_URL=http://10.0.2.2:3105

 

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

에뮬레이터에서 크롬을 켜서 10.0.2.2:3105를 쳤을 때 ok가 뜨나 보세요. 안 뜨면 서버 주소가 잘못된 것입니다.

https://stackoverflow.com/a/16623612/4464863

 

qdial214님의 프로필 이미지
qdial214

작성한 질문수

질문하기