## 추가 작업 할 것들 :
1. SearchBar 연동하기
2. return문 안의 내용구성을 Card.js로 컴포넌트화 시키기
------------------------------------------------------------------------------------
1. 설치파일
ㄱ. firebaseConfig.js 만들어주기 ( 참고링크 : https://radpro.tistory.com/37 )
ㄴ. firebase에 프로젝트 만들고, realtime database의 개인 API 받아오기 ( 참고링크 : https://radpro.tistory.com/38 )
ㄷ. iframe.js 컴포넌트 만들어주기 ( 참고링크 : https://radpro.tistory.com/22 )
2. 기능
ㄱ. <FlatList> 태그를 이용한 리스트를 만든다.
ㄴ. lnfinite scroll를 구현. (데이터가 한번에 로딩되지 않고, 스크를 끝에서 추가로딩됨 = 인스타)
ㄷ. iframe을 이용한 동영상 재생
(유튜브 API를 이용해 url이 아닌 videoID를 따오기 때문에 광고없이 재생. 유튜브 어플도 실행되지 않게해줌.)
ㄹ. ActivityIndicator로 로딩시 로딩중 표시 동그라미 만들어줌
## 데이터 받아오는 스크롤 간격을 설정할 인자는 추가할 예정
3. 사용방법
ㄱ. 우선 상단의 참고링크를 통해 iframe.js와 firebaseConfig.js를 만들었다는 가정하에 시작.
ㄴ. 사용할 모듈부터 import해주자.
import React, { useState, useEffect } from 'react';
import { ActivityIndicator, FlatList, View, Text, Image, StyleSheet, TouchableOpacity, Touchable } from 'react-native';
import { firebase_db } from '../firebaseConfig';
import Iframe from './Iframe';
ㄷ. 기본 틀을 붙여넣어주자.
필자는 export default와 화살표함수를 이용한 함수선언을 선호한다.
=> 본인 취향에 따라 class함수나, export 함수 등 사용 쌉가능
또한, StyleSheet옵션을 이용한 꾸미기를 선호한다.
=> FlatList 사용할 예정이라, renderItem이란 props를 사용해도 좋다. 아니면 그냥 태그안에 style 써도 된다.
export default function Users() {
//const를 이용한 함수 선언 부분
//반환함수로 실제 표기할 태그값 등을 나타낼 부분
return (
<View>
</View>
)
};
//꾸미기 파트
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
}
});
ㄹ. useState와 useEffect를 사용할 것이다.
useState를 이용해 두 가지 hook을 선언해줄것이다.
useEffect를 이용해 앱(또는 화면)이 실행되면 제일 먼저 할 일을 설정해준다.
const [loading, setLoading] = useState(true); // 컴포넌트가 mount되면 실행될 loading
const [state, setState] = useState([]) // 받아올 데이터의 변화에 맞춰 선언해줄 state변수
useEffect(() => {
// useEffect로 선언해줄 조건 적을 곳.
// 여기선 firebase의 API를 쓸 것이다.
setState(state에 대입될 변수이름 넣는 곳)
setLoading(false);
});
}, []);
// 별다른 초기화 값이 없다면 []로 냅두자.(범용)
ㅁ. 이제 firebaseConfig.js를 라우터(=허브)로 사용하여 본인의 firebase의 데이터를 가져올 차례다.
아래의 firebase API를 입력해주자.
여기서, 주의할 점.
1) firebase_db는 내가 firebaseConfig.js에서 export해준 이름이다. 본인이 export한 이름 쓰면 된다.
(예시 firebase, db, database 등...)
2) items는 내 realtime database에 업로드해둔 json데이터의 최상위 key값이다.
본인의 key값으로 변경해주면 된다.
3) setState( ) 괄호 안에 key값을 넣어줌으로써, 이 페이지에 firebase에 업로드해둔 json데이터를 mount해줬다.
(쉽게말해 연동해줬다는 말이다. 다른 프로젝트의 값을 받아오거나 프로젝트 내 json을 받아오고 싶다면
items부터 바꿔서 mount해주면 된다.)
1. 구글에서 제공하는 기본 API
useEffect(() => {
firebase_db.ref('/items').once('value').then((snapshot) => {
console.log("파이어베이스에서 데이터 가져왔습니다!!")
let items = snapshot.val();
setState(items)
setLoading(false);
});
}, []);
//------------------------------------------------------
2. on() 명령어를 사용한 개량형 API
useEffect(() => {
setTimeout(() => {
setLoading(true);
firebase_db
.ref('/items')
.on('value', (snapshot) => {
console.log("items에서 데이터 가져왔습니다!!")
const items = (snapshot.val());
setState(items)
setLoading(false);
})
}, 300)
}, []);
ㅂ. 로딩이 발생하면 ActivityIndicator를 보여줘야 하므로,
if로 조건함수를 간단하게 추가해주자. (return문 전, 함수 선언 부분에 따로 선언해 주면 됨)
if (loading) {
return <ActivityIndicator />;
}
ㅅ. return 부분
준비한 코드와 데이터를 보여줄 차례다.
각자 원하는 데이터로 커스터마이징 해주자.
여기서, item은 이전에 ScrollView로 리스트를 만들때 사용한 content변수랑 같은 포지션으로 생각하면 된다.
(Flatlist 쓸 때, item로 쓰는게 암묵적인 룰이라고 한다.)
return (
<View>
// 기본적으로 감싸준 최외각<View>태그. Flatlist는 ScollView는 호환상의 문제가 발생할 수도 있다.
<Iframe />
// iframe연동을 위해 선언. FlatList로 스크롤 할때, 딸려 올라가지 않도록 따로 해주었다.
<FlatList
data={state}
// <FlatList>파트. data에는 state를 넣어주자
// 이론상 말하자면, firebase의 realtime database에 업로드되어있는 JSON데이터의 Key값인 items를,
// setter변수인 setState가 받아 업데이트해주는데,
// 이를 getter변수인 state가 받아 실행되는 반환값이 되는 것이다.
// state에 대입된 값을 반환해서 보여줘야 하는데, Flatlist에서 data라는 하위 props로 받아서 실행해주는 것.
// 요컨데, items를 받은 setState가 => 다시 state로 넘겨주어 => data로 넘겨주는 방식
renderItem={({ item }) => (
// rederItem이라는 Flatlist의 props를 이용해 {items}에 맞는 밸류값들을 받아올것이다.
// 이 안에서 내용구성을 태그를 이용해서 꾸며주자
<View style={styles.cardContainer}>
<TouchableOpacity style={styles.card}>
<Image style={styles.cardImage} source={{ uri: item.snippet.thumbnails.medium.url }} />
<View style={styles.cardText}>
<Text style={styles.cardTitle} numberOfLines={1}>{item.snippet.title}</Text>
</View>
</TouchableOpacity>
</View>
// 일단 기본적으로 <View>태그로 감싸줬다.
// 반응형을 만들어야 하므로 <TouchableOpacity>속성을 넣어주자.
// ## onPress를 이용한 함수를 넣으려니 오류가 나서 나중에 다시 해보려 한다. ##
// <Image>를 이용해 썸네일도 삽입해줬다.
// <Image>태그와 분리해 주기위해 <View>태그를 하나 더 걸고 그 안에 <Text>태그로 텍스트 들어갈 칸 작성.
// 기호에 따라 추가적인 구성을 만들어 주자!
)}
/>
</View>
);
}
ㅇ. styleSheet 옵션 설정.
return문 안에 넣어둔 <View>와 그 안의 태그들에 설정해둔 style옵션을 설정해주자.
얘는 export default 함수선언문 밖에 심으면 된다.
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
cardContainer: {
// marginTop: 10,
backgroundColor: '#fff',
},
card: {
flex: 1,
//컨텐츠들을 가로로 나열
//세로로 나열은 column <- 디폴트 값임
flexDirection: "row",
margin: 10,
borderBottomWidth: 0.5,
borderBottomColor: "#eee",
paddingBottom: 10
},
cardImage: {
flex: 1,
width: 100,
height: 100,
borderRadius: 10,
},
cardText: {
flex: 2,
flexDirection: "column",
marginLeft: 10,
},
cardTitle: {
fontSize: 20,
fontWeight: "700"
},
cardDesc: {
fontSize: 15
},
cardDate: {
fontSize: 10,
color: "#A6A6A6",
}
});
4. 예제코드
import React, { useState, useEffect } from 'react';
import { ActivityIndicator, FlatList, View, Text, Image, StyleSheet, TouchableOpacity, Touchable } from 'react-native';
import { firebase_db } from '../firebaseConfig';
import Iframe from './Iframe';
export default function Users() {
const [loading, setLoading] = useState(true); // Set loading to true on component mount
const [state, setState] = useState([])
useEffect(() => {
firebase_db.ref('/items').once('value').then((snapshot) => {
console.log("파이어베이스에서 데이터 가져왔습니다!!")
let items = snapshot.val();
setState(items)
setLoading(false);
});
}, []);
if (loading) {
return <ActivityIndicator />;
}
//ActivityIndicator는 로딩 중 돌아가는 동그라미
return (
<View>
<Iframe />
<FlatList
data={state}
renderItem={({ item }) => (
<View style={styles.cardContainer}>
<TouchableOpacity style={styles.card}>
<Image style={styles.cardImage} source={{ uri: item.snippet.thumbnails.medium.url }} />
<View style={styles.cardText}>
<Text style={styles.cardTitle} numberOfLines={1}>{item.snippet.title}</Text>
<Text style={styles.cardDesc} numberOfLines={3}>{item.snippet.description}</Text>
<Text style={styles.cardDate}>{item.snippet.publishedAt}</Text>
<Text>Video ID: {item.id.videoId}</Text>
</View>
</TouchableOpacity>
</View>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
cardContainer: {
// marginTop: 10,
backgroundColor: '#fff',
},
card: {
flex: 1,
//컨텐츠들을 가로로 나열
//세로로 나열은 column <- 디폴트 값임
flexDirection: "row",
margin: 10,
borderBottomWidth: 0.5,
borderBottomColor: "#eee",
paddingBottom: 10
},
cardImage: {
flex: 1,
width: 100,
height: 100,
borderRadius: 10,
},
cardText: {
flex: 2,
flexDirection: "column",
marginLeft: 10,
},
cardTitle: {
fontSize: 20,
fontWeight: "700"
},
cardDesc: {
fontSize: 15
},
cardDate: {
fontSize: 10,
color: "#A6A6A6",
}
});
iframe.js
import React, { useState, useCallback, useRef } from "react";
import { Button, View, Alert } from "react-native";
import YoutubePlayer from "react-native-youtube-iframe";
export default function App() {
const [playing, setPlaying] = useState(false);
const onStateChange = useCallback((state) => {
if (state === "ended") {
setPlaying(false);
Alert.alert("video has finished playing!");
}
}, []);
const togglePlaying = useCallback(() => {
setPlaying((prev) => !prev);
}, []);
return (
<View>
<YoutubePlayer
height={200}
play={playing}
videoId={
"pUoOzaU9rw4"
}
onChangeState={onStateChange}
/>
<Button title={playing ? "pause" : "play"} onPress={togglePlaying} />
</View>
);
}
//videoId를 props를 활용해 할당해보기
--------------------------------------------------------------------------------------------------------------------------------------------------
@수정사항
firebase에서 데이터를 받아오는 기본 API는 once로 되어있다.
이는 데이터를 한 번만 읽는데, 만약 데이터가 바뀔때마다 자동으로 업데이트 되길 희망한다면, on을 사용하는 것이 좋다.
즉, .once() 대신 .on()을 사용하는 방법이다.
두 가지 예제코드는 다음과 같다.
onec를 사용하는 기본 API
setLoading(true);
firebase_db.ref('/ABCD')
.once('value')
.then((snapshot) => {
console.log("ABCD라는 데이터 베이스에서 가져왔습니다!")
let 원하는 변수이름 선언 = snapshot.val()
//스냅샷 형식으로 데이터를 받아온다. 이때, 받아오는 데이터는
//ABCD라는 최상위 키값을 제외하고, 이에 대한 value값만 받아온다.
//스냅샷 형식으로 받아와야 iOS에서도 연동된다.
setState(선언한 변수이름)
//나중에 실제로 데이터를 쓸 부분에 hook으로 넣을 변수에 대입해주는 부분
setTotalDataSource(선언한 변수이름);
//나중에 검색창에 해당하는 토탈 데이터에 넣을 변수에 대입해주는 부분
setLoading(false);
//데이터가 불러와졌으므로, 로딩을 false로 바꿔주는 부분
})
.catch(err => { setLoading(false); setError(err); })
//에라가 발생하면 에러라고 표현해주는 함수를 실행해주는 부분
}, []);
on메소드를 사용하는 변형 API
useEffect(() => {
setTimeout(() => {
setLoading(true);
firebase_db
.ref('/ABCD')
.on('value', (snapshot) => {
console.log("ABCD에서 데이터 가져왔습니다!!")
const 원하는 변수이름 선언 = (snapshot.val());
//마찬가지로 스냅샷으로 데이터를 불러왔다.
//차이점은 once는 'value'나 'child_added'등 불러올 값의 조건만 선언해주고
//딕셔너리를 닫는 형태이다.
//반면, on의 경우, 받아올 값의 조건을 선언해준 뒤에 콤마를 찍고,
//같은 괄호 안에서(즉, on 내부 조건 하에)스냅샷 변수 선언을 해야하기 때문에,
//데이터를 내보낼 조건도 이 안에서 해결해야 한다.
//즉, then을 이용한 내보내기 선언이 안된다.
setState(선언한 변수이름)
setTotalDataSource(선언한 변수이름);
setLoading(false);
})
}, 300)//로딩 시간 설정
}, []);
'React-native > 정리' 카테고리의 다른 글
fetch이해하기 (네트워킹) (0) | 2022.05.24 |
---|---|
FlatList + Iframe 연동 (0) | 2022.05.23 |
기본 학습 (0) | 2022.05.21 |
map함수 돌리는 화면에서 onPress로 경로열기 (Flatlist완성으로 보류) (0) | 2022.05.19 |
유튜브 API로 동영상 Playlist Json 검색 방법 (3분 컷) (0) | 2022.05.16 |