23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
안녕하세요 Teus입니다.
올해부터 DEVOCEAN을 통해서 스터디를 진행하고 있습니다!
제가 준비한 주제는 React를 활용해서 크로스플랫폼을 플랫폼 어플리캐이션을 만드는 React Native입니다!
이번주는 5주차에 진행한 스터디 내용을 다루는 포스팅 입니다!
지난주부터 방향을 틀어서 스터디진도와
각 조별로 4명씩, 총 3개의 조로 나누어 프로젝트를 진행하고 있습니다.
이것과 더불어 1시간 정도는 1주일간 책을 읽어온 부분에 대해서 토의 및 공유를 진행합니다.
하지만 그보다 앞서서, 스터디할때 가장 재미있는 아이스브레이킹 시간이 진행됩니다!
(포크가 떨어지는 저 장면의 과연 뭘까요?)
(???? 정답 아시는분 찾습니다)
이번주는 DEVOCEAN의 왕태웅님이 진행한 넌센스 퀴즈 시간이 있었습니다 :)
아이스브레이킹이 끝난 후 이번주 공부한 내용에 대해서 토의를 진행 했습니다.
자 그럼 이번주에 스터디원들이 어떤것을 공부했는지 살펴보겠습니다.
flutter나 React, 그리고 소규모 어플리캐이션 개발을 하다보면 FireBase라는 친구가 자주 등장합니다.
FireBase는 구글에서 제공하는 웹 DB/API 서버입니다.
별도의 Backend 구축 없이 Data를 저장하거나, Auth를 구축할때 유용하며
초기에는 비용이 발생하지 않기 때문에 어플리캐이션 개발 초창기에 자주 사용됩니다.
FireBase는 Application에 종속됩니다. 때문에 Application에서 FireBase를 접근하기 위해서 android의 gradle 파일, ios의 swirf 파일을 수정하게 됩니다.
(수정해야 할 양이 많아서 이 부분은 내용을로 담지 않았습니다)
FireBase를 어플리캐이션과 연동 했지만, 당연하게도 이것만으로를 FireBase를 이용할 수 없습니다.
FireBase와 API를 사용해서 통신이 필요하며, 이때 FireBase API를 편리하게 사용하기 위한 패키지가 존재합니다.
출처 : https://rnfirebase.io/
yarn add @react-native-firebase/app @react-native-firebase/auth @react-native-firebase/firestore @react-native-firebase/storage
(구글의 API가 아닌 써드파티 API를 쓰는것을 볼 수 있습니다. => 사용의 편의성 때문에...)
FireBase를 이용해서 회원인증을 하기위한 코드 입니다
import auth from '@react-native-firebase/auth';
//로그인
export function signIn({email, password}) {
return auth().signInWithEmailAndPassword(email, password);
}
//회원가입
export function signUp({email, password}) {
return auth().createUserWithEmailAndPassword(email, password);
}
//로그인 상태가 변할때 실행되는 함수
export function subscribeAuth(callback) {
return auth().onAuthStateChanged(callback);
}
//로그아웃
export function signOut() {
return auth().signOut();
}이렇게 정의된 firebase의 API를 aysnc함수로 구현해서 실제 회원인증 및 로그인을 관리하게 됩니다.
const [loading, setLoading] = useState();
const onSubmit = async () => {
Keyboard.dismiss();
//form에서 구조분해를 통해서 email, password를 받고, 이 값으로만 이뤄진 objec인 info를 만들어줌
const {email, password} = form;
const info = {email, password};
setLoading(true);
try {
//비동기 함수인 singUP을 await하여 비동기로 인증을 진행함
const {user} = await signUp(info)
console.log(user);
} catch (e) {
Alert.alert('실패');
console.log(e);
} finally {
setLoading(false);
}
};FireBase는 DB의 역할을 하기 때문에, 회원정보 뿐만 아니라 이미지와같은 데이터 역시 저장이 가능합니다.
이때 FireBase의 Storage를 이용해서 저장하며, API를 활용하는 방법은 아래와 같습니다.
import storage from '@react-native-firebase/storage';
// 업로드할 경로 지정
const reference = storage().ref('/directory/filename.png');
// 파일 저장(uri: 선택한 이미지의 로컬 경로)
await reference.putFile(uri);
// 다운로드할 수 있는(또는 Image를 통해 보여줄 수 있는) URL 생성
const url = await reference.getDownloadURL();위 API 활용 방법을 async function으로 구현하여 활용하게 됩니다.
ES6이후에 JS에서는 Rest연산자와 Spread연산자가 존재합니다.
//rest연산자 : 구조분해 시 나머지 Element를 전부 받아옴
temp = [1, 5, 2, 3, 6]
[a, b, ...c] = temp
/\*
a : 1
b : 5
c : [2, 3, 6]
\*/
//spread연산자 : object에 다른 object를 unpacking해서 넣을 수 있음
[22, ...temp]
//[22, 1, 5, 2, 3, 6]위 처럼 구조분해를 할 때 component의 매개변수를 하나의 변수에 받고, 이것을 바로 componet의 property에 적용하는것이 가능합니다.
이번 내용은 props의 정상적인 동작을 위한 object불변성의 연장입니다.
object를 구조분해 하고, 이 구조분해한 값에 추가적인 key를 추가하는 방법 입니다.
아래를 보시죠
const [form, setForm] = useState({
email: '',
password: '',
confirmPassword: '',
});
const createChangeTextHandler = (name) => (value) => {
setForm({...form, [name]: value});
};
/* 위 표현은 아래 표현과 동일합니다.
하지만 위처럼 표현하는건 Python의 functools.partial과 비슷하기
특정 매개변수값을 고정된 상태의 함수를 콜백으로 넣어주는 용도로 볼 수 있습니다.
const onChangeText = ({ name, text }) => {
setForm({...form, [name]: text});
}
*/만약 {...form, name: value} 이라고 했다면 literal로 'name' 이라는 key가 추가됩니다.
하지만 대괄호로 묶어줌으로써 해당 이름이 literal이 아닌 변수의 값을 가지고 오라고 설정하게 됩니다.
이렇게하면 기존의 object의 data는 유지한 상태로, key가 바뀐 새로운 object를 만들어서 setState를 하는것이 가능합니다.
예전 포스팅에서 있었지만, useRef는 animation이나 아니면 component의 Focus를 관리할때 사용한다고 하였습니다.
function BorderedInput({hasMarginBottom, ...rest}, ref) {
return (
<TextInput
style={[styles.input, hasMarginBottom && styles.margin]}
ref={ref}
{...rest}
/>
);
}
(...)
//component의 export 시에 React.forwardRef를 추가해줌
export default React.forwardRef(BorderedInput);import BorderedInput from '../components/BorderedInput';
(...)
function SignInScreen({navigation, route}) {
(...)
const passwordRef = useRef();
const confirmPasswordRef = useRef();
return (
<KeyboardAvoidingView
style={styles.keyboardAvoidingView}
behavior={Platform.select({ios: 'padding'})}>
<SafeAreaView style={styles.fullscreen}>
<Text style={styles.text}>PublicGallery</Text>
<View style={styles.form}>
<BorderedInput
hasMarginBottom
placeholder="이메일"
value={form.email}
onChangeText={createChangeTextHandler('email')}
autoCapitalize="none"
autoCorrect={false}
autoCompleteType="email"
keyboardType="email-address"
returnKeyType="next"
//해당 component에서 submit을 할 경우 해당 ref를 받은 component가 focus가 가게됨
onSubmitEditing={() => passwordRef.current.focus()}
/>
<BorderedInput
placeholder="비밀번호"
secureTextEntry
hasMarginBottom={isSignUp}
value={form.password}
onChangeText={createChangeTextHandler('password')}
//useRef의 반환값을 받아서 focus를 받을 component인것을 알려줌
ref={passwordRef}
returnKeyType={isSignUp ? 'next' : 'done'}
onSubmitEditing={() => {
if (isSignUp) {
confirmPasswordRef.current.focus();
} else {
onSubmit();
}
}}
/>
(...)어플리캐이션에서 유저의 카메라 or 이미지에 접근하려면 권한이 필요합니다.
RN프로젝트의 ios와 android의 gradle을 수정해 줌 으로써 어플리캐이션에서 해당 기능에 대한 접근이 가능해집니다.
ios/pjt_name/Info.plist
(...)
<key>NSPhotoLibraryUsageDescription</key>
<string>$(PRODUCT_NAME) would like access to your photo gallery</string>
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) would like to use your camera</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>$(PRODUCT_NAME) would like to save photos to your photo gallery</string>
</dict>
</plist>android/app/src/main/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.publicgallery<닉네임>">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
(...)이후 yarn add react-native-image-picker 통해서 RN에서 image를 선택할 수 있는 package를 프로젝트에 추가해 줍니다.
해당 패키지에선 launchCamera, launchImageLibrary 두개의 기능을 사용하게 되고, 이름에서 볼 수 있듯 Camera와 ImageLibrary에 접근할 수 있습니다.
const onSelectImage = () => {
launchImageLibrary(
{
mediaType: 'photo',
maxWidth: 512,
maxHeight: 512,
includeBase64: Platform.OS === 'android',
},
(res) => {
console.log(res);
},
);
};
return (
<View style={styles.block}>
<Pressable onPress={onSelectImage}>
<Image
style={styles.circle}
//image-picker로 선택된 이미지의 uri정보를 통해서 <Image> tag에서 image를 보여줌
source={{uri: response?.assets[0]?.uri}} />
</Pressable>
/* res의 출력 예시
{
"assets": [
{
"fileName": "6EF3415F-4DD4-405D-A019-2F3010BB5398.jpg",
"fileSize": 221192,
"height": 340,
"type": "image/jpg",
"uri": "file:///Users/velopert/Library/Developer/CoreSimulator/Devices/44E0A134-AB93-4564-8AC6-044A06296A74/data/Containers/Data/Application/E3B964F0-CEC7-42DE-A7C8-847A04D3450D/tmp/6EF3415F-4DD4-405D-A019-2F3010BB5398.jpg",
"width": 512
}
]
}
*/각 조별로 프로젝트를 진행하고 있으며, 각 조별로는 진행 상황이 다 다릅니다!
1조 : 무언가 아이디어를 가지고 CI공모하는중....
2조 : 일단을 빨리 만들어보자! 를 시작으로 어플리캐이션 화면 설계중
3조 : 본격적으로 일한번 크게 벌려볼라고 회의하는중
3개조의 프로젝트가 어떻게 진행될지 흥미진진합니다!
이제 겨우 뭔가 방향성을 찾아가고있는 RN스터디 였습니다!
다음주 6주차로 다시 돌아옵니다!
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.