본문 바로가기
React Native

0050. 실전 FE 개발 배우기7 - 로그인 화면 만들기, TextInput의 다양한 옵션 사용하기(Feat. 진짜 개발 시작!)

by 보초코더^_^;; 2024. 1. 25.
반응형

섹션 1. 리액트 네비게이션

3강. 로그인 화면 만들기

 

칠드런이 하나만 오는 때가 생기는데, 그때는 Tab.Group을 사용해서 묶어주면 된다.

<Tab.Group></Tab.Group>

<T>
	<Children></Children>
	<Children></Children>
	<Children></Children>
</>

이렇게 프레그먼트로 묶어주는 것과 같은 이치다.

 

이렇게 쓰고 이메일을 입력하라는 부분을 누르면 키보드가 올라온다.

 

TextInput을 썼기 때문

 

알림을 뜨게 만드는 Alert.alert

 

 

이제 꾸미기만 하면 된다.

import React, { useCallback, useState } from "react";
import { Alert, Pressable, StyleSheet, Text, TextInput, View } from "react-native";

function SignIn() {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');

    const onChangeEmail = useCallback((text) => {
        setEmail(text);
    }, []);
    const onChangePassword = useCallback((text) => {
        setPassword(text);
    }, []);

    const onSubmit = useCallback(() => {
        Alert.alert( '알림', '안녕~');
    }, []);

    const canGoNext = !email || !password; //변수명을 깔끔하게 지으면 다른 사람이 이해하기 쉽다. 좋은 코드의 조건
    return (
        <View>
            <View style={styles.inputWrapper}>
                <Text style={styles.label}>이메일(ID)</Text>
                <TextInput 
                    style={styles.textInput}
                    placeholder="이메일을 입력해주세요." 
                    onChangeText={onChangeEmail} 
                />
            </View>
            <View style={styles.inputWrapper}>
                <Text style={styles.label}>비밀번호</Text>
                <TextInput 
                    style={styles.textInput}
                    placeholder="비밀번호를 입력해주세요." 
                    onChangeText={onChangePassword} />
            </View>
            <View style={styles.buttonZone}>
                <Pressable 
                    onPress={onSubmit} 
                    style={
                        canGoNext 
                        ? styles.loginButton 
                        : StyleSheet.compose(styles.loginButton, styles.loginButtonActive)
                    } 
                    disabled={canGoNext}>
                    <Text style={styles.loginButtonText}>로그인</Text>
                </Pressable>
                <Pressable>
                    <Text>회원가입하기</Text>
                </Pressable>
            </View>
        </View>
    );
}

const styles = StyleSheet.create({
    inputWrapper: {
        padding: 20,
    },
    textInput: {
        padding: 5,
        borderBottomWidth: StyleSheet.hairlineWidth, // 보이는 것중에서 가장 얇은거
    },    
    label: {
        fontWeight: 'bold',
        fontSize: 16,
        marginBottom: 20,
    
    },
    loginButton: {
        backgroundColor: 'gray',
        paddingHorizontal: 20,
        paddingVertical: 10,
        borderRadius: 5,
        marginTop: 10,
        marginBottom: 10,
    },
    loginButtonActive: {
        backgroundColor: 'blue',
    },
    loginButtonText: {
        fontSize: 20,
        color: 'white',
    },
    buttonZone: {
        alignItems: 'center',
    },
});

export default SignIn;

 

이렇게 쓰면 다음과 같이 나온다.

 

ID 또는 비밀번호가 입력되지 않으면 로그인 버튼이 회색으로 변한다.

 

4강. TextInput 사용하기

secureTextEntry 하면 비밀번호가 블러처리된다.

좀 더 확실하게 하려면 secureTextEntry={true}를 입력해 주면 된다.

boolean 타입이다.

 

TextInput에는 상당히 많은 옵션들이 있다.

다양한 옵션을 확인하려면 공식문서를 참조하면 된다.

요즘 인증문자 오면 자동으로 입력하는 OTP 같은 것도 잘 되어 있다.

 

https://reactnative.dev/docs/textinput#importantforautofill-android

 

TextInput · React Native

A foundational component for inputting text into the app via a keyboard. Props provide configurability for several features, such as auto-correction, auto-capitalization, placeholder text, and different keyboard types, such as a numeric keypad.

reactnative.dev

 

우측 점을 보면 안드로이드, IOS에서 적용되는 점들이다.

검은 점 : Android only

초록 점 : IOS only

 

그래서 둘 다 적용되는 것을 사용하려면 점이 없는 것을 사용하면 된다.

위의 공식 문서는 목록만 제공해 주고 어떤 역할인지까지는 나와있지 않아서 따로 구글링을 해야 한다.

 

저런 화살표 모양도 다 바꿀 수 있다.

 

각 기능의 옵션들이 궁금하면 정의로 이동을 누른다.

예를 들어, keyboardType이 있으면 어떤 옵션이 있는지 알기 어렵다. 그러면 정의로 이동한다음에

옵션들이 뭐가 있는지를 확인하면 된다.

decimal-pad는 숫자만 나와있는 패드를 의미한다.

 

import { NativeStackScreenProps } from "@react-navigation/native-stack";
import React, { useCallback, useRef, useState } from "react";
import { Alert, Pressable, StyleSheet, Text, TextInput, View } from "react-native";
import { RootStackParamList } from "../../App";


type SignInScreenProps = NativeStackScreenProps<RootStackParamList, 'SignIn'>;
function SignIn({ navigation } : SignInScreenProps) {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const emailRef = useRef<TextInput | null>(null);  //generic
    const passwordRef = useRef<TextInput | null>(null);

    const onChangeEmail = useCallback((text) => {
        setEmail(text);
    }, []);
    const onChangePassword = useCallback((text) => {
        setPassword(text);
    }, []);

    const onSubmit = useCallback(() => {
        if(!email || !email.trim()) { //trim : 좌우공백 없애기
            return Alert.alert('알림', '이메일을 입력해주세요.');
        }
        if(!password || !password.trim()) {
            return Alert.alert('알림', '비밀번호를 입력해주세요.');
        }
        Alert.alert( '알림', '안녕~ 로그인 되었습니다~');
    }, [email, password]); //검증로직

    const toSignUp = useCallback(() => {
        navigation.navigate('SignUp');
    }, [navigation]);

    const canGoNext = !email || !password; //변수명을 깔끔하게 지으면 다른 사람이 이해하기 쉽다. 좋은 코드의 조건
    return (
        <View>
            <View style={styles.inputWrapper}>
                <Text style={styles.label}>이메일(ID)</Text>
                <TextInput 
                    style={styles.textInput}
                    placeholder="이메일을 입력해주세요."
                    value={email} 
                    onChangeText={onChangeEmail}
                    importantForAutofill="yes"
                    autoComplete="email"
                    textContentType="emailAddress"
                    keyboardType="email-address"
                    returnKeyType="next"
                    onSubmitEditing={() => {
                        passwordRef.current?.focus(); //밑에 passwordRef에 focus해준다는 것. 비밀번호칸으로 이동.
                    }}
                    blurOnSubmit={false} //키보드 내려감 방지
                    ref={emailRef}
                    clearButtonMode="while-editing" //아이폰에서만 적용, 우측에 X표시 떠서 누르면 없어지는거
                />
            </View>
            <View style={styles.inputWrapper}>
                <Text style={styles.label}>비밀번호</Text>
                <TextInput 
                    style={styles.textInput}
                    placeholder="비밀번호를 입력해주세요."
                    value={password}
                    onChangeText={onChangePassword}                     
                    importantForAutofill="yes"
                    autoComplete="password"
                    textContentType="password"       
                    keyboardType="default" //비밀번호를 숫자로만 받고싶으면! decimal-pad 숫자키보드 팝업             
                    ref={passwordRef}
                    onSubmitEditing={onSubmit} //비밀번호 입력하고 엔터치면 바로 키보드 내려가게(엔터치면 하는 동작 지정, 사용성UP)
                    secureTextEntry={true}
                />
            </View>
            <View style={styles.buttonZone}>
                <Pressable 
                    onPress={onSubmit} 
                    style={
                        canGoNext 
                        ? styles.loginButton 
                        : StyleSheet.compose(styles.loginButton, styles.loginButtonActive)
                    } 
                    disabled={canGoNext}>
                    <Text style={styles.loginButtonText}>로그인</Text>
                </Pressable>
                <Pressable onPress={toSignUp}>
                    <Text>회원가입하기</Text>
                </Pressable>
            </View>
        </View>
    );
}

const styles = StyleSheet.create({
    inputWrapper: {
        padding: 20,
    },
    textInput: {
        padding: 5,
        borderBottomWidth: StyleSheet.hairlineWidth, // 보이는 것중에서 가장 얇은거
    },    
    label: {
        fontWeight: 'bold',
        fontSize: 16,
        marginBottom: 20,
    
    },
    loginButton: {
        backgroundColor: 'gray',
        paddingHorizontal: 20,
        paddingVertical: 10,
        borderRadius: 5,
        marginTop: 10,
        marginBottom: 10,
    },
    loginButtonActive: {
        backgroundColor: 'blue',
    },
    loginButtonText: {
        fontSize: 20,
        color: 'white',
    },
    buttonZone: {
        alignItems: 'center',
    },
});

export default SignIn;

최종코드

 

전체적으로 한번 다시 따라가면서 만들어봐야 정확하게 이해할 수 있을 것 같다.

이렇게 해서 실제 화면이 나오니까 재미가 붙기 시작한 게 가장 큰 수확이다.

반응형