동아리/노라

[황금청춘] 회원가입 페이지 구현 1 (ReactNative)

hyunh404 2024. 5. 31. 13:52
728x90

 

 

회원가입은 전화번호로 진행하며,

즉, 전화번호를 앱의 아이디로 활용한다.

 

 

또한 서비스 이용동의를 위해 체크 박스도 구현했으며, 

 

앱이라는 특성 상

가장 먼저 KeyboardAvoidingView를 사용해 키보드가 열릴 때 화면을 자동으로 조정하여 값을 입력할 수 있도록 했다.

또한 ScrollView로 화면이 길어질 경우 스크롤이 가능하게 코드를 작성해주었다.

 

<KeyboardAvoidingView
        style={{ flex: 1 }}
        behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
        <ScrollView contentContainerStyle={styles.scrollContainer}>
          <View style={styles.topContainer}>
            <Text style={styles.title}>전화번호로 회원가입</Text>
            <Text style={styles.subtitle}>전화번호는 아이디로 사용됩니다.</Text>
            <TextInput             
              style={[
              styles.input,
              isFocused && styles.focusedInput
            ]}
            value={phoneNumber}
            onChangeText={(text) => setPhoneNumber(formatPH(text))}
            keyboardType="phone-pad"
            placeholder="01012345678"
            onFocus={() => setIsFocused(true)}
            onBlur={() => setIsFocused(false)}
            />
          </View>
       </ScrollView>
</KeyboardAvoidingView>

 

 

 

1. 전화번호 입력

 

전화 번호 입력 필드는 포맷함수를 정의해 전화번호를 입력할 때 숫자만 남기고 형식에 맞게 저장되도록 변환시켜 주었다.

slice 메서드를 통해 각 숫자들을 편집했으며 형식도 직접 설정해 정의했다.

예를들어,

01012345678을 전화번호로 입력하면 포맷함수에 의해 010-1234-5678 형식으로 자동으로 변환되어 입력된다.

 

const formatPH = (number) => {
    let formatNum = number.replace(/\D/g, '');
    if (formatNum.length > 3 && formatNum.length <= 7) {
      formatNum = `${formatNum.slice(0, 3)}-${formatNum.slice(3)}`;
    } else if (formatNum.length > 7) {
      formatNum = `${formatNum.slice(0, 3)}-${formatNum.slice(3, 7)}-${formatNum.slice(7, 11)}`;
    }
    return formatNum;
  }

 

 

 

728x90

 

 

2. 이용 동의 체크 박스

 

 

체크 박스를 만들기 위해 일반적으로 제공되는 체크 박스 형식이 아닌 스타일을 커스텀하기 위해 직접 컴포넌트를 구성해주었다.

 

TouchableOpacity 를 사용해 표시하고 싶은 아이콘을 설정하고 체크할 수 있는 버튼을 만들었다.

컴포넌트이기 때문에 체크 박스에 들어갈 내용과 onPress 속성 요소들은 모두 Props로 받아서 유동적으로 컴포넌트를 활용할 수 있도록 했다.

 

 

따라서 만들어둔 체크박스 컴포넌트를 사용해 서비스 이용동의 목록을 만들 수 있었다.

 

컴포넌트에 label, onPress 속성을 Props로 전달하고 있으며,

체크가 되었는지 상태를 관리하기 위한 checked 속성도 같이 Props로 전달해주었다.

 

 

이외에도 모든 체크박스에 동의할 수 있도록 '모두 동의' 체크박스를 설정해 모든 체크박스의 상태를 관리할 수 있게 했다.

 

<View style={styles.checkboxContainer}>
            <Checkbox
              checked={isChecked.all}
              onPress={() => handleCheckBox('all')}
            />
            <Text style={{ position: 'absolute', left: 50, fontSize: 18 }}>아래 사용 약관에 모두 동의합니다.</Text>
            <TouchableOpacity
              onPress={toggleCheckboxes}
              style={{ position: 'absolute', left: 340, top: 4 }}
            >
              <Icon
                name={isToggled ? 'up' : 'down'}
                size={20}
                color="#000"
              />
            </TouchableOpacity>
            <View style={styles.underline} />
            {showCheckboxes && (
              <View style={styles.indentCheckboxContainer}>
                <Checkbox
                  label="서비스 이용약관 동의(필수)"
                  checked={isChecked.terms}
                  onPress={() => handleCheckBox('terms')}
                />
                <Checkbox
                  label="개인정보 수집 이용 동의(필수)"
                  checked={isChecked.privacy}
                  onPress={() => handleCheckBox('privacy')}
                />
                <Checkbox
                  label="커뮤니티 가이드 동의(필수)"
                  checked={isChecked.community}
                  onPress={() => handleCheckBox('community')}
                />
                <Checkbox
                  label="위치기반 서비스 이용 동의(선택)"
                  checked={isChecked.location}
                  onPress={() => handleCheckBox('location')}
                />
              </View>
            )}
          </View>

 

 

 

이때 checked 상태는 useState 객체 형태로 관리 했으며, 

handleCheckBox 함수를 정의해 '모두 동의' 체크박스가 다른 체크박스들을 한번에 관리할 수 있도록 코드를 작성했다.

 

추가적으로 모든 체크박스가 동의된다면 이용 동의 목록이 toggle 형식으로 접어지도록 toggle 함수를 정의해 적용함으로써 화면을 좀 더 깔끔하게 정리할 수 있었다.

 

const [isChecked, setIsChecked] = useState({
    all: false,
    terms: false,
    privacy: false,
    community: false,
    location: false,
  });
 
const handleCheckBox = (key) => {
    if (key === 'all') {
      const newValue = !isChecked.all;
      setIsChecked({
        all: newValue,
        terms: newValue,
        privacy: newValue,
        community: newValue,
        location: newValue,
      });
      setShowCheckboxes(!showCheckboxes);
      setIsToggled(!isToggled);
    } else {
      const newState = { ...isChecked, [key]: !isChecked[key] };
      newState.all = newState.terms && newState.privacy && newState.community && newState.location;
      setIsChecked(newState);
    }
  };

 

 


 

 

3. 나이 선택 라디오 박스

 

 

다음으로, 황금청춘 앱은 만 50세 이상인 사용자를 타켓층으로 구현하고 있기 때문에 나이를 구분할 수 있는 라디오 박스를 만들어 주었다.

 

  • 만 50세 이상입니다.
  • 만 50세 미만입니다.

 

2가지 선택지를 기준으로 라디오 박스를 만들었고, 

사용자가 나이를 선택하면 정의해둔 handleAgeSelection 함수가 호출되어 선택값을 상태에 저장해 관리하게 된다.

 

'만 50세 미만입니다.' 를 선택하면 회원가입 불가 안내 모달창이 나오도록 화면을 구현했다.

 

const handleAgeSelection = (selectedAge) => {
    setAge(selectedAge);
    if (selectedAge === 'below') {
      setIsModalVisible(true);
    }
  };
 
<View style={styles.radioContainer}>
            <TouchableOpacity style={styles.radioOption} onPress={() => handleAgeSelection('above')}>
              <View style={styles.radioCircle}>
                {age === 'above' && <View style={styles.selectedRb} />}
              </View>
              <Text style={styles.radioText}>만 50세 이상입니다.</Text>
            </TouchableOpacity>
            <TouchableOpacity style={styles.radioOption} onPress={() => handleAgeSelection('below')}>
              <View style={styles.radioCircle}>
                {age === 'below' && <View style={styles.selectedRb} />}
              </View>
              <Text style={styles.radioText}>만 50세 미만입니다.</Text>
            </TouchableOpacity>
</View>

 

 

모달 창은 리액트 네이티브에서 제공하는 라이브러리를 사용해 구현했다.

제공되는 라이브러리는 기본적으로 애니메이션 효과나 배경 클릭 처리 등 내장되어 있는 기능들이 존재하기 때문에 코드구현에 있어서 유연함을 주고자 선택하게 되었다.

 

 

또한, 커스터마이징도 가능하기 때문에 모달창의 위치와 css는 직접 디자인에 맞게 수정해서 적용해주었다.

 

 

결과적으로,

완성된 페이지를 보여주며 다음 글에서 회원가입 구현 내용을 이어가보도록 하겠다.

 

회원가입 페이지 1

728x90

'동아리 > 노라' 카테고리의 다른 글

[황금청춘] 온보딩 페이지 구현 (ReactNative)  (0) 2024.05.31