ํฌ์ŠคํŠธ

๐ŸŒ’ React Native ๋ฆฌ์•กํŠธ ๋„ค์ดํ‹ฐ๋ธŒ - ์ด๊ฒƒ์ €๊ฒƒ ๋ฉ”๋ชจ

2023-12-05. 14:57
Mobile Programming Test ๊ธ€ ๊ณ„์Šน


๐Ÿ’ซ ์ค‘์ฒฉ๋œ ScrollView ๋ฐฉํ–ฅ์˜ ์ œ์•ฝ


@ TODO : 212p

๐Ÿ’ซ Javascript, Typescript


ํ•จ์ˆ˜ ๊ตฌํ˜„ ์ฝ”๋“œ Func(): A ์—์„œ : A๋Š” ํ•จ์ˆ˜๊ฐ€ A๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ์˜๋ฏธ.

Pick ํƒ€์ž…
โ†’ ์ œ๋„ค๋ฆญ ํƒ€์ž…, ๋Œ€์ƒ ํƒ€์ž…์˜ ์ „์ฒด ์†์„ฑ ์ค‘ ํ•„์š”ํ•œ ์†์„ฑ๋งŒ ์„ ํƒํ•˜์—ฌ ๋ฐ˜ํ™˜

1
type NewType = Pick<SomeType, 'SomePropertyA' | 'SomePropertyB'>

๊ฐ์ฒด๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์†์„ฑ์„ ์•Œ๊ธฐ์œ„ํ•ด์„œ, console.log(Objects.keys(๊ฐœ์ฒด)) ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ’ซ Fetch


GET/POST/PUT/DELETE๋ฅผ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก, Javascript ์—”์ง„์—์„œ ๊ธฐ๋ณธ ์ œ๊ณตํ•˜๋Š” API์ด๋‹ค.

blob, json, text ๊ฐ™์€ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š” Response ํƒ€์ž… ๊ฐ์ฒด๋ฅผ Promise ๋ฐฉ์‹์œผ๋กœ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

Promise ๊ฐ์ฒด๋Š” then ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป์–ด์•ผ ํ•œ๋‹ค.
then ๋ฉ”์„œ๋“œ๋Š” ๋˜ ๋‹ค๋ฅธ Promise ๊ฐ์ฒด๋‚˜ ์–ด๋–ค ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

then์„ ์—ฐ๋‹ฌ์•„ ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋ฅผ then-์ฒด์ธ์ด๋ผ ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ์ •์˜
function fetch(input: RequestInfo, init?:RequestInit): Promise<Response>
interface Response
{
	blob(): Promise<Blob>;
	json(): Promise<any>;
	text(): Promise<string>;
}

// ์‚ฌ์šฉ
fetch('RequestInfo Like URL')

fetch('RequestInfo Like URL')
	.then((res) => res.json())
	.then((blabla) => someMethod(blabla))
	.catch((error: Error) => console.log(error.message))

๐Ÿ’ซ ํ‚ค์›Œ๋“œ


ActivityIndicator ์ฝ”์–ด ์ปดํฌ๋„ŒํŠธ
โ†’ ํšŒ์ „ํ•˜๋Š” ์•„์ด์ฝ˜, react-native ํŒจํ‚ค์ง€

1
2
3
4
5
export default function Timer()
{
	const [loading, setLoading] = useState(false)
	return ( { loading && (<ActivityIndicator>) } )
}

๐Ÿ’ซ JSX์—์„œ if๋ฌธ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•


@ U ์ค‘๊ฐ„๊ณ ์‚ฌ ์ถœ์ œ :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
export default function App()
{
	const isLoading = true
	if (isLoading)
	{
		return
		{
			<SafeAreaView>
				<Text>Loading...</Text>
			</SafeAreaView>
		}
	}

	return
	{
		<SafeAreaView>
			<Text>Hello JSX World !</Text>
		</SafeAreaView>
	}
}
1
2
3
4
5
6
7
8
9
10
11
{ /* ๋‹จ์ถ•ํ‰๊ฐ€ Short Circuit Evaluation */ }
export default function App()
{
	const isLoading = true
	<SafeAreaView>
		{ /* A && B : undefined */ }
		{ /* JSX Parser, undefined or null ๋ฌด์‹œ */ }
		{isLoading && <Text>Loading...</Text>}
		{!isLoading && <Text>Hello JSX World !</Text>}
	</SafeAreaView>
}
1
2
3
4
5
6
7
8
9
{ /* ๋‹จ์ถ•ํ‰๊ฐ€ Short Circuit Evaluation */ }
export default function App()
{
	const isLoading = true
	const children = isLoading ?
		(<Text>Hello JSX World !</Text>) :
		(<Text>Loading...</Text>)
	return <SafeAreaView>{children}</SafeAreaView>
}

๐Ÿ’ซ ํ•จ์ˆ˜์ปดํฌ๋„ŒํŠธ ์†์„ฑ ์ •์˜ ๋ฐ ์ „๋‹ฌ ๋ฐฉ๋ฒ•


@ U ์ค‘๊ฐ„๊ณ ์‚ฌ ์ถœ์ œ :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
{ /* XML(Markup Language) : Attribute, TS(Programming Language) : Property */ }
<Person name = "Jack" age = {22}/>

{ /* ์•ˆ์ชฝ ์ค‘๊ด„ํ˜ธ : ๊ฐ์ฒด ์ƒ์„ฑ, ๋ฐ”๊นฅ์ชฝ ์ค‘๊ด„ํ˜ธ : JSX ๊ตฌ๋ฌธ */ }
<Person person ={{name: 'Jack', age: 32}}/>

{ /* @ */ }
{ /* ๊ฐ€์ƒ DOM ๊ฐ์ฒด = createElement(์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ or ๋ฌธ์ž์—ด, `์†์„ฑ ๊ฐ์ฒด`, ์ž์‹ ์ปดํฌ๋„ŒํŠธ) */ }

{ /* or */ }

{ /* ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- */ }

export type IPerson
{
	id: string
	createdDate : Date
	counts:
	{
		comment: number
		retweet: number
	}
}

export const createRandomPerson = (): IPerson =>
{
	return
	{
		id: ~,
		...
	}
}

{ /* ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- */ }

import React from 'react'
{ /* import type : TSโ†’JS ์ปดํŒŒ์ผ ๋•Œ๋งŒ ํ•„์š”ํ•œ 'ํƒ€์ž…', ๋ฐ˜๋ฉด ํด๋ž˜์Šค๋Š” ๋‚จ์Œ */ }
{ /* FC : Function Component */ }
import type {FC} from 'react'
import * as D from './~'

export type PersonProps =
{
	person: D.IPerson
}

const Person: FC<PersonProps> = ({person}) =>
{
	{ /* ๊ฐ์ฒด ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅํ•  ์ˆ˜ ์—†์–ด์„œ, ๊ณต๋ฐฑ 2๊ฐœ ๋ถ™์€ ๋ฌธ์ž์—ด๋กœ, Like .ToString */ }
	return <Text>{JSON.stringify(person, null, 2)}</Text>
}

export default Person

{ /* ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- */ }

import Person from './~'
import * as D from './~'

const person = D.createRandomPerson()

export default function App()
{
	return <ArrowComponent person = {person} />
}

๐Ÿ’ซ ์ž”์—ฌ์—ฐ์‚ฐ์ž


@ U ์ค‘๊ฐ„๊ณ ์‚ฌ ์ถœ์ œ :

ESNext JS์™€ TS, Rest Operator - ์ž”์—ฌ ์—ฐ์‚ฐ์ž ์ง€์›

1
2
3
4
5
6
7
8
9
10
11
12
let address: any
{
	country: 'Korea',
	city: 'Seoul',
	address1: 'Gangnam-gu',
	address2: '~',
	address3: '~'
}
const {country, city, ...detail} = address

{ /* detail = { address1, address2, address3 } */ }

๐Ÿ’ซ ์–•์€ ๋ณต์‚ฌ & ๊นŠ์€ ๋ณต์‚ฌ


@ U ๊ธฐ๋ง๊ณ ์‚ฌ ์ถœ์ œ : TODO, ์ „๊ฐœ ์—ฐ์‚ฐ์ž

๐Ÿ’ซ React.Fragment ์ปดํฌ๋„ŒํŠธ


@ U ์ค‘๊ฐ„๊ณ ์‚ฌ ์ถœ์ œ :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, {Fragment} from 'react'

{ /* JSX = XML, ๋‹ค์Œ๊ฐ™์ด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ ์—†์ด๋Š” ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์˜ฌ ์ˆ˜ ์—†์Œ */ }
<SafeAreaView />
<View />

{ /* Fragment : ์‹ค์ฒด๊ฐ€ ์žˆ๋Š” ๊ฑด ์•„๋‹ˆ์ง€๋งŒ, XML ๋ฌธ๋ฒ•์ด ์š”๊ตฌํ•˜๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ ์—ญํ• ๋กœ ๋™์ž‘ํ•˜๋„๋ก */ }
<Fragment>
	<SafeAreaView />
	<View />
</Fragment>

{ /* ๋‹จ์ถ• ๊ตฌ๋ฌธ */ }
<>
	<SafeAreaView />
	<View />
</>

๐Ÿ’ซ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์˜ ๊ต์ง‘ํ•ฉ ํƒ€์ž… ๊ตฌ๋ฌธ


@ U ์ค‘๊ฐ„๊ณ ์‚ฌ ์ถœ์ œ :

TS, Algebraic Data Type - ADT - ๋Œ€์ˆ˜ ๋ฐ์ดํ„ฐ ํƒ€์ž… ์ง€์›

ํ•ฉ์ง‘ํ•ฉ ํƒ€์ž…
โ†’ type A_OR_B = A | B

๊ต์ง‘ํ•ฉ ํƒ€์ž…
โ†’ type A_AND_B = A & B

๐Ÿ’ซ useStyle ์ปค์Šคํ…€ ํ›… ๋งŒ๋“ค๊ธฐ


@ U ๊ธฐ๋ง๊ณ ์‚ฌ ์ถœ์ œ : TODO, useStyle ์ปค์Šคํ…€ ํ›… ๋งŒ๋“ค๊ธฐ (6์žฅ), 400p

์ด ๊ธฐ์‚ฌ๋Š” ์ €์ž‘๊ถŒ์ž์˜ CC BY 4.0 ๋ผ์ด์„ผ์Šค๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.