노마드 강의를 끝낸 후 직접 만들려다보니 엄청난 오류를 맞이했다🤣🤣
나는 전에 만들어뒀던 firebase 프로젝트에 지금 만들려고하는 웹앱도 연동시켜 같은 웹과 같은 서비스를 공유하도록 할 생각이었다.
문제는 내가 firebase auth에 설정한 도메인 제한 설정때문에 expo로 Auth 서비스를 사용할 수 없다.
Expo는 기본적으로 도메인이 없기 때문에 내가 설정한 도메인 필터에 자동으로 걸러진다.
이 문제를 해결하기 위해 고군분투했지만 우선은 다른 과제부터 해결하기로 했다.
그 중 하나가 React-navigation의 사용이다.
❓ 이게 뭐냐고 하면 기존 React 프레임워크에서 Router 역할과 비슷한 역할을 수행한다고 보면 된다.
굉장히 간단할 것 같지만 부끄럽게도 이것도 구현하는 데 굉장히 많은 오류를 경험했다.
먼저 위의 네비게이션을 적용하기 위한 로그인과 회원가입 폼을 만들어보자.
import React from "react";
import {
View,
Text,
StyleSheet,
TouchableOpacity,
TextInput,
Button,
} from "react-native";
import Firebase from "../firebase";
class Login extends React.Component {
state = {
email: ``,
password: ``,
};
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.inputBox}
value={this.state.email}
placeholder="Email"
onChangeText={(email) => this.setState({ email })}
autoCapitalize="none"
/>
<TextInput
style={styles.inputBox}
value={this.state.password}
placeholder="Password"
onChangeText={(password) => this.setState({ password })}
secureTextEntry={true}
autoCapitalize="none"
/>
<TouchableOpacity style={styles.button} onPress={this.handleLogin}>
<Text style={styles.buttonText}>Login</Text>
</TouchableOpacity>
<Button title="Don't have an account yet? Sign up" />
</View>
);
}
}
export default Login;
✔ Login.js
import React from "react";
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
} from "react-native";
import Firebase from "../firebase";
class Signup extends React.Component {
state = {
name: "",
email: "",
password: "",
};
handleSignUp = () => {
const { email, password } = this.state;
Firebase.auth()
.createUserWithEmailAndPassword(email, password)
.then(() => this.props.navigation.navigate("ProfileScreen"))
.catch((error) => console.log(error));
};
render() {
return (
<View style={styles.container}>
{/* <TextInput
style={styles.inputBox}
value={this.state.name}
placeholder="Full name"
onChangeText={(name) => this.setState({ name })}
/> */}
<TextInput
style={styles.inputBox}
value={this.state.email}
placeholder="Email"
onChangeText={(email) => this.setState({ email })}
autoCapitalize="none"
/>
<TextInput
style={styles.inputBox}
value={this.state.password}
placeholder="Password"
onChangeText={(password) => this.setState({ password })}
secureTextEntry={true}
autoCapitalize="none"
/>
<TouchableOpacity style={styles.button} onPress={this.handleSignUp}>
<Text style={styles.buttonText}>Signup</Text>
</TouchableOpacity>
</View>
);
}
}
export default Signup;
✔ Signup.js
import React from "react";
import { View, Text, StyleSheet } from "react-native";
class Profile extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Profile Screen</Text>
</View>
);
}
}
export default Profile;
✔ Profile.js
스타일에 관한 부분은 중요하지 않기에 생략했다.
이러한 컴포넌트가 세개가 있을 때 한 컴포넌트에서 다른 컴포넌트로의 이동은 어떻게 하면 좋을까?
그러한 정답을 제공해주는 게 react-navigation이다.
이걸 사용하면 다른 컴포넌트의 이동은 물론 props까지 전달할 수 있다.
그 방법은 다음과 같다.
우선 세가지 컴포넌트의 상위 컴포넌트가 되는 App 컴포넌트로 간다.
App 컴포넌트에서는 당연히 렌더링할 위의 3가지 컴포넌트들을 import하고 react-navigation도 import한다.
import React from "react";
import { StyleSheet, Text, View } from "react-native";
import Login from "./screens/Login";
import Signup from "./screens/Signup";
import Profile from "./screens/Profile";
import { createSwitchNavigator, createAppContainer } from "react-navigation";
const AuthSwitch = createSwitchNavigator(
{
LoginScreen: Login,
SingupScreen: Signup,
ProfileScreen: Profile,
},
{ initialRouteName: "SingupScreen" }
);
const AppContainer = createAppContainer(AuthSwitch);
export default AppContainer;
보면 순서가 있다.
createSwitchNavigator로 AuthSwitch를 만들어 준후 이 AuthSwitch를 이용하여 createAppContainer로 AppContainer를 생성한다.
- AuthSwitch 생성
- AppContainer 생성
이런 식이다.
그리고 이 AppContainer를 Routing 해주면 기존 React의 Router 컴포넌트처럼 동작한다.
그 중에 "먼저 무슨 컴포넌트를 띄우지?"에 대한 고민을 initialRouteName이 해결해준다.
여기에 제일 먼저 띄우고 싶은 컴포넌트를 설정해주자.
그리고 다시 SignupScreen으로 가자!
import React from "react";
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
} from "react-native";
class Signup extends React.Component {
state = {
name: "",
email: "",
password: "",
};
handleSignUp = () => {
this.props.navigation.navigate("ProfileScreen");
};
render() {
return (
<View style={styles.container}>
{/* <TextInput
style={styles.inputBox}
value={this.state.name}
placeholder="Full name"
onChangeText={(name) => this.setState({ name })}
/> */}
<TextInput
style={styles.inputBox}
value={this.state.email}
placeholder="Email"
onChangeText={(email) => this.setState({ email })}
autoCapitalize="none"
/>
<TextInput
style={styles.inputBox}
value={this.state.password}
placeholder="Password"
onChangeText={(password) => this.setState({ password })}
secureTextEntry={true}
autoCapitalize="none"
/>
<TouchableOpacity style={styles.button} onPress={this.handleSignUp}>
<Text style={styles.buttonText}>Signup</Text>
</TouchableOpacity>
</View>
);
}
}
export default Signup;
TouchableOpacity에 onPress 이벤트리스너를 추가한 걸 보자.
🖐🖐 그전에 잠깐!
TouchableOpacity 컴포넌트는 Button 대신에 많이 쓰이는 react-native의 컴포넌트다.
이게 Button 대신에 쓰이는 이유는 Button은 iOS와 안드로이드에서 다르게 보이기 때문에 관리의 어려움이 있기 때문이다.
✅그럼 다시 본론으로 돌아와서!
onPress라는 이벤트 리스너는 직감적으로 알 수 있겠지만 터치로 눌렀을 때 함수를 실행한다.
실행되는 함수의 내용은 this.props.navigation.navigate("ProfileScreen")이다.
요 3가지 컴포넌트들은 navigation 안에 포함된 녀석들이기 때문에 props안에 navigation이 포함된다.
navigation은 navigate를 통해 원하는 컴포넌트로 전환하는 함수를 가지고 있다.
이게 전부지만 지금부터는 내가 만난 오류에 대해서 설명하겠다. 🚫🚫
아마 위의 코드를 그대로 실행하면 expo에서 엄청난 오류를 맞이할 것이다.
그 이유는 웃기게도 react-navigation을 install 받는 것만으로는 필수 패키지를 충족시키지 못하기 때문이다.
이것 때문에 오류의 늪에 빠져 참 고생을 많이 했는데 해결법은 다음 링크에 포함되어 있다.
https://reactnavigation.org/docs/getting-started
여기를 보면 react-navigation 외에 어떤 패키지를 install하고 import 해줘야하는지를 설명해주고 있다.
이 과정을 거쳐야 비로소 에러 없이 navigation의 기능을 사용할 수 있다.
오늘은 여기까지 하도록 하자. 아르바이트도 있으니까.
내일은 navigation의 기능을 좀 더 파고 auth 서비스를 이용한 회원가입 기능을 전부 구현해볼 것이다.
그리고 마지막으로 로그인폼을 작성하면서 새롭게 안 사실에 대해서 추가적으로 기술하자.
모바일에서 텍스트를 입력할 때 알파벳의 경우 첫글자가 자동적으로 대문자로 설정되는 경우가 있다.
이런 경우 때문에 굳이 수고스럽게 shift를 한 번 클릭해주고 입력해야한다.
하지만 TextInput에 authcapitalize 속성을 "none"으로 설정하면 첫글자를 자동으로 대문자로 설정하지 않는다.
개꿀!
그리고 react-native는 html 태그를 사용하지 않기 때문에 따로 password type의 input이 없다.
그래서 비밀번호를 입력할 때 그 내용이 훤히 다 보인다.
이걸 방지하기 위한게 TextInput의 secureTextEntry 속성이다.
이걸 true로 설정하면 입력한 내용이 *로 치환된다.
오늘은 여기까지!
그럼 이만~~~
'프로그래밍 > REACT-NATIVE' 카테고리의 다른 글
REACT-NATIVE(EXPO) SNS 프로젝트 시작 (6) (1) | 2021.07.28 |
---|---|
REACT-NATIVE(EXPO) SNS 프로젝트 시작 (5) (0) | 2021.07.26 |
REACT-NATIVE(EXPO) SNS 프로젝트 시작(3) (0) | 2021.07.24 |
REACT-NATIVE(EXPO) SNS 프로젝트 시작(2) (0) | 2021.07.24 |
REACT-NATIVE(EXPO) SNS 프로젝트 시작 (1) (0) | 2021.07.24 |
댓글