๐Ÿญ Note #2021-01-27

Ko Seoyoungยท2021๋…„ 1์›” 27์ผ
0

์˜ค๋Š˜์€ ์ž‘์€ ๋ฒ„๊ทธ ๋‘๊ฐœ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ , ๋™์˜์ƒ์„ ๋ณด์—ฌ์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ต์ฒด, ์• ๋„๋ฆฌํ‹ฑ์Šค(Analytics) ์ด๋ฒคํŠธ์™€ ํŒŒ๋ผ๋ฏธํ„ฐ์— ๊ด€ํ•œ ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

1๏ธโƒฃ

ํ•”์˜ ์ƒ์„ธ๋ฆฌ๋ทฐ์—์„œ๋Š” ์œ ํŠœ๋ธŒ ๋™์˜์ƒ์„ ํ†ตํ•ด ํŒจ์…˜ ์•„์ดํ…œ์„ ์ƒ์„ธํžˆ ์ถ”์ฒœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ react-native๋กœ ๊ฐœ๋ฐœํ•œ ์•ฑ์—์„œ ๋™์˜์ƒ์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š”๋ฐ, ๊ธฐ์กด์—๋Š” react-native-youtube-iframe์„ ํ†ตํ•ด ์ด ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„๋˜์–ด ์žˆ์—ˆ๋‹ค. ์ด npm ํŒจํ‚ค์ง€๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ์œ ํŠœ๋ธŒ ์•ฑ๋ณด๋‹ค ๋” ์•ˆ์ •์ ์œผ๋กœ ์•Œ๋ ค์ง„ ์›น๋ทฐ ํ”Œ๋ ˆ์ด์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ React Native ์•ฑ์— ์˜์ƒ์„ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.


๊ฐœ๋… #1

  • ๋จผ์ €, iframe์€ HTML iframe์€ ์›น ํŽ˜์ด์ง€ ๋‚ด์— ์›น ํŽ˜์ด์ง€๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.
  • ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์—์„œ ์›น๋ทฐ๋Š” html์—์„œ์˜ iframe๊ณผ ๋น„์Šทํ•œ ๊ฐœ๋…์œผ๋กœ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์—์„œ html์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” View์ด๋‹ค. (์•ˆ๋“œ๋กœ์ด๋“œ์˜ ๊ฒฝ์šฐ framework์— ๋‚ด์žฅ๋œ ์ปดํฌ๋„ŒํŠธ ๋ทฐ(View)ํ˜•ํƒœ์ธ WebView๋กœ ์•ฑ์— ์ž„๋ฒ ๋”ฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.)
  • ์›น๋ทฐ๋Š” ๋‹จ์ˆœํ•˜๊ฒŒ, ์›น ํŽ˜์ด์ง€๋ฅผ ๋ณด๊ธฐ์œ„ํ•ด๋„ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ ์•ˆ์—์„œ HTML์„ ํ˜ธ์ถœํ•˜์—ฌ ์•ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ํ˜•ํƒœ์˜ ์•ฑ์„ ๊ฐœ๋ฐœํ•˜๋Š”๋ฐ์—๋„ ๋งŽ์ด ์‚ฌ์šฉ๋œ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ios๋Š” ํ…Œ์ŠคํŠธ ์‹œ ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ๋Š”๋ฐ ์•ˆ๋“œ๋กœ์ด๋“œ ํ…Œ์ŠคํŠธ ๊ฒฝ์šฐ ์˜์ƒ ์žฌ์ƒ/์ •์ง€, ๋ชจ๋‹ฌ์ด ์—ด๋ฆฌ๊ณ  ๋‹ซํžˆ์ง€๊ฐ€ ์•Š๋Š” ๋“ฑ์˜ ๋ฒ„๊ทธ๊ฐ€ ์žˆ์–ด์„œ ์ด๋ฅผ react-native-youtube-sdk ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜๋„๋ก ๋ฐ”๊พธ๋Š” ์ž‘์—…์„ ํ–ˆ๋‹ค. ์ด๊ฒƒ์€ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋“ฑ๊ณผ ๊ฐ™์€ sdk๋ฅผ ์ด์šฉํ•˜์—ฌ ๋™์˜์ƒ์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ ๊ตฌํ˜„ ์ž์ฒด๋Š” ๊ธฐ์กด ์ฝ”๋“œ ๋ช‡์ค„๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๋˜์–ด์„œ ์–ด๋ ต์ง€ ์•Š์•˜๋Š”๋ฐ, ๋™์˜์ƒ ์‚ฝ์ž…์ด ์ƒ๊ฐ๋ณด๋‹ค ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„๋˜์–ด ์žˆ๋˜ ์ ์ด ์‹ ๊ธฐํ–ˆ๋‹ค. ๊ทธ๋ƒฅ <YouTubePlayer /> ์ปดํฌ๋„ŒํŠธ๋งŒ ํ•˜๋ผ๋Š”๋ฐ๋กœ ์ž˜ ์‚ฌ์šฉํ•˜๋ฉด ๋จ. ๊ทธ๋ฆฌ๊ณ  ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ ์•ˆ์— ์žˆ๋Š” YouTubePlayer์˜ ๋ฉ”์†Œ๋“œ๋Š” ref๋ฅผ ์‚ฌ์šฉํ•ด ์ปดํฌ๋„ŒํŠธ์˜ Dom์— ์ ‘๊ทผํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


2๏ธโƒฃ

๋˜! ์˜ค๋Š˜์€ ์•ฑ์˜ ์ธ์‚ฌ์ดํŠธ๋ฅผ ์ž๋™์œผ๋กœ ์ธก์ •ํ•˜์—ฌ ์ œ๊ณตํ•ด์ฃผ๋Š” firebase Analytics๊ฐ€ ์šฐ๋ฆฌ ์–ดํ”Œ์˜ ์–ด๋””์„œ ์“ฐ์ด๋Š”์ง€์— ๊ด€ํ•œ ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉฐ ์• ๋„๋ฆฌํ‹ฑ์Šค๊ฐ€ ์–ด๋–ป๊ฒŒ ์•ฑ์— ์ ์šฉ๋˜๋Š”์ง€ ์•Œ๊ฒŒ๋˜์—ˆ๋‹ค.

ํ•”์—์„œ๋Š” ์ด๋ฏธ (์•Œ๋ฆผ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š”) cloud messaging, (์‹ค์ œ ์‚ฌ์šฉ์ž๋“ค์ด ์•ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜์— ๋Œ€ํ•ด์„œ ์‰ฝ๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š”) crashlytics, (๋งํฌ๋งŒ์œผ๋กœ๋„ ์•ฑ์˜ ์›ํ•˜๋Š” ์ปจํ…์ธ ์— ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ํ•ด์ฃผ๋Š” (์•ฑ์ด ์„ค์น˜ ๋˜์–ด ์žˆ์ง€ ์•Š์•„๋„ ์„ค์น˜ ํ›„ ๊ทธ ๋งํฌ๋กœ ๊ฐ€๊ฒŒ ํ•ด์คŒ)) dynamic Link ๋“ฑ์˜ ๋งŽ์€ ๊ธฐ๋Šฅ๋“ค์„ react native firebase ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ Firebase Analytics๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

์ด๋ฏธ ๊ธฐ๋Šฅ์€ ๊ตฌํ˜„๋˜์–ด์žˆ์—ˆ์ง€๋งŒ ๊ตฌํ˜„๋œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์–ด๋–ค ๊ณณ์—์„œ ์ธ์‚ฌ์ดํŠธ๋ฅผ ์ธก์ •ํ•˜๋Š”์ง€, ์–ด๋–ป๊ฒŒ ์•ฑ์— ์• ๋„๋ฆฌํ‹ฑ์Šค๋ฅผ ์ ์šฉํ•˜๋Š”์ง€ ์•Œ๊ฒŒ๋˜์—ˆ๋‹ค.

๊ฐœ๋… #2

  • Predefined Events: Firebase๊ฐ€ ๋ฏธ๋ฆฌ ์ •์˜ํ•ด๋†“์€ ์ด๋ฒคํŠธ๋“ค
    (์ด๋ฒคํŠธ ์œ ํ˜•์— ๋”ฐ๋ผ ๋งž์ถค ๋ณด๊ณ ์„œ๊ฐ€ ์ œ๊ณต๋˜๋ฏ€๋กœ ๋˜๋„๋ก ๊ธฐ๋ณธ ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๋‹ค!)
  • Custom Event: ์ด๋ฆ„๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ์„ค์ •ํ•œ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ
    (ํ”„๋กœ์ ํŠธ๋‹น ๊ณ ์œ  Parameter๋ฅผ ์ตœ๋Œ€ 50๊ฐœ๊นŒ์ง€๋งŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋‚จ์šฉํ•˜๋ฉด Parameter ๊ฐœ์ˆ˜์ œํ•œ์— ๊ฑธ๋ ค ์• ์จ ์ˆ˜์ง‘ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ ๋ฆด ์ˆ˜๋„ ์žˆ๋‹ค)
// Predefined Events ์‚ฌ์šฉ ์˜ˆ) ์•„์ดํ…œ ๋””ํ…Œ์ผ ํŽ˜์ด์ง€ ์ ‘๊ทผ์‹œ ํ˜ธ์ถœ
export const logViewItem = async (item: IItem) => {
  await analytics.logViewItem({
    items: [ItemSerializer(item)],
  });
};

// Custom Event ์‚ฌ์šฉ ์˜ˆ) ์ข‹์•„์š” ํด๋ฆญ ์‹œ ํ˜ธ์ถœ
export const logLikeReview = async (
  content_type: string,
  content_id: string,
) => {
  await analytics.logEvent('like_review', {
    content_type,
    content_id,
  });
};

3๏ธโƒฃ

๊ทธ๋ž˜์„œ ํ›…์ด ๋ญ”๊ฐ€์š”?

  • Hook์€ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฆฌ์•กํŠธ state์™€ ์ƒ๋ช…์ฃผ๊ธฐ ๊ธฐ๋Šฅ์„ ์—ฐ๋™ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋กœ, class ์—†์ด ๋ฆฌ์•กํŠธ์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. (Hook์€ class์•ˆ์—์„œ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค)

  • ๋งค๋ฒˆ ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ์ฝ”๋“œ ๋ผ์ธ์œผ๋กœ ๋ฆฌ์•กํŠธ ์ฝ”์–ด๊ฐ€ ์‹คํ–‰ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•œํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋งค๋ฒˆ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ๋กœ์ง๋“ค์„ ์ ๋Š” ๊ณณ.


ํ›… ๊ฒ€์‚ฌ ๋กœ์ง

  1. React๋Š” Element๋งŒ(render tree - key) ๊ธฐ์–ตํ•˜๊ณ , hook์€ uniqueํ•˜๊ฒŒ ๊ธฐ์–ตํ•˜์ง€ ์•Š๋Š”๋‹ค. hook์€ ์ข…๋ฅ˜์™€ ์ˆœ์„œ๋งŒ ๊ธฐ์–ต.
// ์ด๋Ÿฌ๋ฉด ์•ˆ๋จ
items.forEach(() โ‡’ {

const [liking, setLiking] = useState(false);

});
  1. ํ˜ธ์ถœ๋œ hook์˜ ๊ฐœ์ˆ˜๊ฐ€ ๋‹ค๋ฅด๋ฉด ์—๋Ÿฌ, ์ข…๋ฅ˜๊ฐ€ ๋‹ค๋ฅด๋ฉด ์—๋Ÿฌ
// ์—๋Ÿฌ๋‚จ
const {data} = useItem(id);

if(!data) {
	return <></>;
}

const [liking, setLiking] = useState(false);

ํ›…์ด ์™œ ์ข‹๋‚˜์š”?

  1. ํ›…์„ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ์ƒํƒœ ๊ด€๋ จ ๋กœ์ง๋“ค์„ ์ถ”์ƒํ™” ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด ๋…์ง‘์ ์ธ ํ…Œ์ŠคํŠธ์™€ ๋กœ์ง ์žฌ์‚ฌ์šฉ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

  2. ํด๋ž˜์Šค์˜ componentDidMount, componentDidUpdate, componentWillUnmount์—์„œ ์ƒ๋ช…์ฃผ๊ธฐ ๋ฉ”์„œ๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฝ”๋“œ๋“ค์„
    ํ›…์„ ํ†ตํ•ด ๋กœ์ง์— ๊ธฐ๋ฐ˜์„ ๋‘” ์ž‘์€ ํ•จ์ˆ˜๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    โ‡’ Event listener ์ •์˜, ๋ฐ”์ธ๋”ฉ, ๋ฐ”์ธ๋”ฉ ํ•ด์ œ 3๊ฐ€์ง€๋ฅผ 1๊ฐ€์ง€ hook์—์„œ ๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  3. ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋ณด๋‹ค ๊ฐ„๊ฒฐํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ›…์ด ์—†์œผ๋ฉด ์™œ ์•ˆ ์ข‹๋‚˜์š”?

class ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ stateful ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด HOC(๊ณ ์ฐจํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ) ๋˜๋Š” render props์˜ ํ˜•ํƒœ๋กœ state ๊ฐ’์„ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ์ „๋‹ฌ ๋ฐ›์•„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ์ฝ”๋“œ๊ฐ€ ์ง๊ด€์ ์ด์ง€ ์•Š๊ณ  Wrapper Hell์— ๋น ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


Etc.

React ๋ Œ๋”๋ง ์ดํ•ด ๋ฐ ์ตœ์ ํ™” (With Hook)

๋ฆฌ์•กํŠธ๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘?


Refs, ์ฐธ๊ณ ํ•˜๋ฉด ์ข‹์€ ์ž๋ฃŒ

์กฐ๋Œ€ํ˜‘์˜ ๋ธ”๋กœ๊ทธ:์•ˆ๋“œ๋กœ์ด๋“œ ์›น๋ทฐ(Webview)์˜ ์ดํ•ด์™€ ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฐฉ์•ˆ

Firebase Analytics, BigQuery์—†์ด ์–ด๋””๊นŒ์ง€ ๊ฐ€๋Šฅํ• ๊นŒ

React Native Firebase doc

React-Native Firebase Analytics ์„ค์ • ํŒ!

profile
Web Frontend Developer ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป #React #Nextjs #ApolloClient

0๊ฐœ์˜ ๋Œ“๊ธ€