정보실

웹학교

정보실

javascript React을 위해 알아야 할 JavaScript

본문

React를 배우고 사용할 때 숙지해야 할 JavaScript 기능


내가 사용한 다른 프레임 워크와 비교하여 React에서 가장 좋아하는 것 중 하나는 JavaScript를 사용할 때 노출되는 방식입니다. 

템플릿 DSL (JSX는 현명한 JavaScript로 컴파일)이 없으며, 컴포넌트 API는 React Hooks를 추가하여 더 단순해졌으며 프레임 워크는 핵심 UI 외부에서 해결하려는 추상화를 거의 제공하지 않습니다.


따라서 JavaScript 기능을 배우는 것이 React를 사용하여 응용 프로그램을 효과적으로 구축하는 것이 좋습니다. 

그래서 여기에 React 작업을 최대한 효율적으로 수행 할 수 있도록 학습에 시간을 할애하는 것이 좋습니다.


https://kentcdodds.com/blog/javascript-to-know-for-react 


템플릿 리터럴 (Template Literals) 


템플릿 리터럴은 초강력을 가진 일반 문자열과 같습니다.


const greeting = 'Hello'
2const subject = 'World'
3console.log(`${greeting} ${subject}!`) // Hello World!
4
5// this is the same as:
6console.log(greeting + ' ' + subject + '!')
7
8// in React:
9function Box({className, ...props}) {
10 return <div className={`box ${className}`} {...props} />
11}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals


속기 속성 이름 (Shorthand property names) 


이것은 매우 일반적이며 유용하므로 지금은 생각하지 않아도 됩니다.


const a = 'hello'
2const b = 42
3const c = {d: [true, false]}
4console.log({a, b, c})
5
6// this is the same as:
7console.log({a: a, b: b, c: c})
8
9// in React:
10function Counter({initialCount, step}) {
11 const [count, setCount] = useCounter({initialCount, step})
12 return <button onClick={setCount}>{count}</button>
13}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#New_notations_in_ECMAScript_2015


화살표 함수 (Arrow functions) 


화살표 함수는 JavaScript에서 함수를 작성하는 또 다른 방법이지만 의미상 몇 가지 차이점이 있습니다. 운 좋게도 React land에서는 클래스가 아닌 프로젝트에서 후크를 사용하는 경우 이 문제에 대해 걱정할 필요가 없지만 화살표 함수는 익명의 함수와 암시적인 리턴을 허용하므로, 화살표 함수을 충분히 사용하고 싶습니다.


const getFive = () => 5
2const addFive = a => a + 5
3const divide = (a, b) => a / b
4
5// this is the same as:
6function getFive() {
7 return 5
8}
9function addFive(a) {
10 return a + 5
11}
12function divide(a, b) {
13 return a / b
14}
15
16// in React:
17function TeddyBearList({teddyBears}) {
18 return (
19 <ul>
20 {teddyBears.map(teddyBear => (
21 <li key={teddyBear.id}>
22 <span>{teddyBear.name}</span>
23 </li>
24 ))}
25 </ul>
26 )
27}

위의 예에서 주목할 점은 여는 괄호와 닫는 괄호입니다. 이는 JSX로 작업 할 때 화살표 함수의 암시 적 반환 기능을 활용하는 일반적인 방법입니다. 


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions


비구조화 (Destructuring)


비구조화는 아마도 내가 가장 좋아하는 JavaScript 기능일 것입니다. 객체와 배열을 항상 구조화합니다 (useState를 사용하는 경우에도 마찬가지입니다). 나는 그것이 얼마나 선언적인지를 좋아합니다.


// const obj = {x: 3.6, y: 7.8}
2// makeCalculation(obj)
3
4function makeCalculation({x, y: d, z = 4}) {
5 return Math.floor((x + d + z) / 3)
6}
7
8// this is the same as
9function makeCalculation(obj) {
10 const {x, y: d, z = 4} = obj
11 return Math.floor((x + d + z) / 3)
12}
13
14// which is the same as
15function makeCalculation(obj) {
16 const x = obj.x
17 const d = obj.y
18 const z = obj.z === undefined ? 4 : obj.z
19 return Math.floor((x + d + z) / 3)
20}
21
22// in React:
23function UserGitHubImg({username = 'ghost', ...props}) {
24 return <img src={`https://github.com/${username}.png`} {...props} />
25}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment


function nestedArrayAndObject() {
2 // refactor this to a single line of destructuring...
3 const info = {
4 title: 'Once Upon a Time',
5 protagonist: {
6 name: 'Emma Swan',
7 enemies: [
8 {name: 'Regina Mills', title: 'Evil Queen'},
9 {name: 'Cora Mills', title: 'Queen of Hearts'},
10 {name: 'Peter Pan', title: `The boy who wouldn't grow up`},
11 {name: 'Zelena', title: 'The Wicked Witch'},
12 ],
13 },
14 }
15 // const {} = info // <-- replace the next few `const` lines with this
16 const title = info.title
17 const protagonistName = info.protagonist.name
18 const enemy = info.protagonist.enemies[3]
19 const enemyTitle = enemy.title
20 const enemyName = enemy.name
21 return `${enemyName} (${enemyTitle}) is an enemy to ${protagonistName} in "${title}"`
22}


매개 변수 기본값 (Parameter defaults) 


이것은 내가 항상 사용하는 또 다른 기능입니다. 함수의 기본값을 선언적으로 표현하는 정말 강력한 방법입니다.


// add(1)
2// add(1, 2)
3function add(a, b = 0) {
4 return a + b
5}
6
7// is the same as
8const add = (a, b = 0) => a + b
9
10// is the same as
11function add(a, b) {
12 b = b === undefined ? 0 : b
13 return a + b
14}
15
16// in React:
17function useLocalStorageState({
18 key,
19 initialValue,
20 serialize = v => v,
21 deserialize = v => v,
22}) {
23 const [state, setState] = React.useState(
24 () => deserialize(window.localStorage.getItem(key)) || initialValue,
25 )
26
27 const serializedState = serialize(state)
28 React.useEffect(() => {
29 window.localStorage.setItem(key, serializedState)
30 }, [key, serializedState])
31
32 return [state, setState]
33}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters


Rest/Spread 


... 구문은 값 모음에서 작동하는 일종의 "컬렉션"구문으로 생각할 수 있습니다. 나는 항상 그것을 사용하고 그것을 어떻게 그리고 어떻게 사용할 수 있는지 배우는 것이 좋습니다. 실제로는 상황에 따라 다른 의미가 있으므로 뉘앙스를 배우면 도움이 될 것입니다.


const arr = [5, 6, 8, 4, 9]
2Math.max(...arr)
3// is the same as
4Math.max.apply(null, arr)
5
6const obj1 = {
7 a: 'a from obj1',
8 b: 'b from obj1',
9 c: 'c from obj1',
10 d: {
11 e: 'e from obj1',
12 f: 'f from obj1',
13 },
14}
15const obj2 = {
16 b: 'b from obj2',
17 c: 'c from obj2',
18 d: {
19 g: 'g from obj2',
20 h: 'g from obj2',
21 },
22}
23console.log({...obj1, ...obj2})
24// is the same as
25console.log(Object.assign({}, obj1, obj2))
26
27function add(first, ...rest) {
28 return rest.reduce((sum, next) => sum + next, first)
29}
30// is the same as
31function add() {
32 const first = arguments[0]
33 const rest = Array.from(arguments).slice(1)
34 return rest.reduce((sum, next) => sum + next, first)
35}
36
37// in React:
38function Box({className, ...restOfTheProps}) {
39 const defaultProps = {
40 className: `box ${className}`,
41 children: 'Empty box',
42 }
43 return <div {...defaultProps} {...restOfTheProps} />
44}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters


ESModules 


최신 도구를 사용하여 앱을 빌드 하는 경우 모듈을 지원할 가능성이 높습니다. 사소한 크기의 응용 프로그램이라도 코드 재사용 및 구성을 위해 모듈을 사용해야 할 수 있으므로 구문이 작동하는 방식을 배우는 것이 좋습니다.


export default function add(a, b) {
2 return a + b
3}
4
5/*
6 * import add from './add'
7 * console.assert(add(3, 2) === 5)
8 */
9
10export const foo = 'bar'
11
12/*
13 * import {foo} from './foo'
14 * console.assert(foo === 'bar')
15 */
16
17export function subtract(a, b) {
18 return a - b
19}
20
21export const now = new Date()
22
23/*
24 * import {subtract, now} from './stuff'
25 * console.assert(subtract(4, 2) === 2)
26 * console.assert(now instanceof Date)
27 */
28
29// in React:
30import React, {Suspense, Fragment} from 'react'

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export


또 다른 자료로서, 나는 이 문법에 대해 전체적으로 이야기했고 여기서 그 이야기를 볼 수 있습니다. 


Ternaries 


나는 삼항을 좋아합니다. 그들은 아름답게 선언적입니다. 특히 JSX에서.


const message = bottle.fullOfSoda
2 ? 'The bottle has soda!'
3 : 'The bottle may not have soda :-('
4
5// is the same as
6let message
7if (bottle.fullOfSoda) {
8 message = 'The bottle has soda!'
9} else {
10 message = 'The bottle may not have soda :-('
11}
12
13// in React:
14function TeddyBearList({teddyBears}) {
15 return (
16 <React.Fragment>
17 {teddyBears.length ? (
18 <ul>
19 {teddyBears.map(teddyBear => (
20 <li key={teddyBear.id}>
21 <span>{teddyBear.name}</span>
22 </li>
23 ))}
24 </ul>
25 ) : (
26 <div>There are no teddy bears. The sadness.</div>
27 )}
28 </React.Fragment>
29 )
30}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator


Array Methods 


배열은 환상적이며 항상 배열 방법을 사용합니다! 아마도 다음 방법을 가장 자주 사용합니다.

  • find
  • some
  • every
  • includes
  • map
  • filter
  • reduce

여기 몇 가지 예가 있어요.

const dogs = [
2 {
3 id: 'dog-1',
4 name: 'Poodle',
5 temperament: [
6 'Intelligent',
7 'Active',
8 'Alert',
9 'Faithful',
10 'Trainable',
11 'Instinctual',
12 ],
13 },
14 {
15 id: 'dog-2',
16 name: 'Bernese Mountain Dog',
17 temperament: ['Affectionate', 'Intelligent', 'Loyal', 'Faithful'],
18 },
19 {
20 id: 'dog-3',
21 name: 'Labrador Retriever',
22 temperament: [
23 'Intelligent',
24 'Even Tempered',
25 'Kind',
26 'Agile',
27 'Outgoing',
28 'Trusting',
29 'Gentle',
30 ],
31 },
32]
33
34dogs.find(dog => dog.name === 'Bernese Mountain Dog')
35// {id: 'dog-2', name: 'Bernese Mountain Dog', ...etc}
36
37dogs.some(dog => dog.temperament.includes('Aggressive'))
38// false
39
40dogs.some(dog => dog.temperament.includes('Trusting'))
41// true
42
43dogs.every(dog => dog.temperament.includes('Trusting'))
44// false
45
46dogs.every(dog => dog.temperament.includes('Intelligent'))
47// true
48
49dogs.map(dog => dog.name)
50// ['Poodle', 'Bernese Mountain Dog', 'Labrador Retriever']
51
52dogs.filter(dog => dog.temperament.includes('Faithful'))
53// [{id: 'dog-1', ..etc}, {id: 'dog-2', ...etc}]
54
55dogs.reduce((allTemperaments, dog) => {
56 return [...allTemperaments, ...dog.temperaments]
57}, [])
58// [ 'Intelligent', 'Active', 'Alert', ...etc ]
59
60// in React:
61function RepositoryList({repositories, owner}) {
62 return (
63 <ul>
64 {repositories
65 .filter(repo => repo.owner === owner)
66 .map(repo => (
67 <li key={repo.id}>{repo.name}</li>
68 ))}
69 </ul>
70 )
71}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array


약속과 비동기 / 기다리기 (Promises and async/await) 


이것은 큰 주제이며 그들과 잘 지내려면 약간의 연습과 시간이 걸릴 수 있습니다. 약속은 JavaScript 생태계의 어느 곳에서나 존재하며, React가 해당 생태계에 얼마나 확고한 지에 따라 어디든지 있습니다 (사실, React 자체는 약속을 내부적으로 사용합니다).


약속은 비동기 코드를 관리하는 데 도움이 되며 타사 라이브러리뿐만 아니라 많은 DOM API에서 반환 됩니다. 비동기 / 대기 구문은 약속을 처리하기 위한 특수 구문입니다. 두 사람이 함께 갑니다.


function promises() {
2 const successfulPromise = timeout(100).then(result => `success: ${result}`)
3
4 const failingPromise = timeout(200, true).then(null, error =>
5 Promise.reject(`failure: ${error}`),
6 )
7
8 const recoveredPromise = timeout(300, true).then(null, error =>
9 Promise.resolve(`failed and recovered: ${error}`),
10 )
11
12 successfulPromise.then(log, logError)
13 failingPromise.then(log, logError)
14 recoveredPromise.then(log, logError)
15}
16
17function asyncAwaits() {
18 async function successfulAsyncAwait() {
19 const result = await timeout(100)
20 return `success: ${result}`
21 }
22
23 async function failedAsyncAwait() {
24 const result = await timeout(200, true)
25 return `failed: ${result}`
26 }
27
28 async function recoveredAsyncAwait() {
29 let result
30 try {
31 result = await timeout(300, true)
32 return `failed: ${result}` // this would not be executed
33 } catch (error) {
34 return `failed and recovered: ${error}`
35 }
36 }
37
38 successfulAsyncAwait().then(log, logError)
39 failedAsyncAwait().then(log, logError)
40 recoveredAsyncAwait().then(log, logError)
41}
42
43function log(...args) {
44 console.log(...args)
45}
46
47function logError(...args) {
48 console.error(...args)
49}
50
51// This is the mothership of all things asynchronous
52function timeout(duration = 0, shouldReject = false) {
53 return new Promise((resolve, reject) => {
54 setTimeout(() => {
55 if (shouldReject) {
56 reject(`rejected after ${duration}ms`)
57 } else {
58 resolve(`resolved after ${duration}ms`)
59 }
60 }, duration)
61 })
62}
63
64// in React:
65function GetGreetingForSubject({subject}) {
66 const [isLoading, setIsLoading] = React.useState(false)
67 const [error, setError] = React.useState(null)
68 const [greeting, setGreeting] = React.useState(null)
69
70 React.useEffect(() => {
71 async function fetchGreeting() {
72 try {
73 const response = await window.fetch('https://example.com/api/greeting')
74 const data = await response.json()
75 setGreeting(data.greeting)
76 } catch (error) {
77 setError(error)
78 } finally {
79 setIsLoading(false)
80 }
81 }
82 setIsLoading(true)
83 fetchGreeting()
84 }, [])
85
86 return isLoading ? (
87 'loading...'
88 ) : error ? (
89 'ERROR!'
90 ) : greeting ? (
91 <div>
92 {greeting} {subject}
93 </div>
94 ) : null
95}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await


결론 


물론 React 앱을 빌드 할 때 유용한 많은 언어 기능이 있지만, 이것들은 내가 반복해서 사용하는 내가 좋아하는 것 중 일부입니다. 이 정보가 도움이 되길 바랍니다.



  • 트위터로 보내기
  • 페이스북으로 보내기
  • 구글플러스로 보내기
  • 카카오톡으로 보내기

페이지 정보

조회 4회 ]  작성일19-11-09 12:18

웹학교