지영이의 개발 블로그
러닝 리액트 2판 정리 (1~2장) 본문
CHAPTER 1
1.3.3
노드 설치하기
노드는 풀스택 애플리케이션을 구축할 수 있는 런타임 환경이다. 노드는 오픈 소스이며 윈도우,맥,리눅스 등의 플랫폼에 설치할 수 있다. 익스프레스 서버를 구축할 때 노드를 사용한다.
리액트를 다루려면 노드를 설치해야 한다 .
<node 설치 여부 확인>
$ node -v
npm
노드를 설치하면 자동으로 노드 패키지 관리자인 npm도 함께 설치된다.자바스크립트 커뮤니ㅌ에서는 같은 일을 하는 프레임 워크나 라이브러리, 도우미 함수드을 중복으로 작성하는 일이 없도록 하기 위해 엔지니어들이 오픈소스를 공유하는데 리액트자체도 유용한 npm 라이브러리의 예이다.
새로운 프로젝트를 밑바닥부터 시작하면서 의존 관계를 포함하고 싶다면 다음 명령을 실행하자.
프로젝트를 초기화 하고 package.json 파일을 만들어준다 .
npm i -y
npm 으로 패키지를 설치하고 싶으면 다음과 같이 입력하자
npm i 패키지이름
npm 으로 패키지를 제거하고 싶다면
npm remove 패키지이름
yarn
얀은 페이스북 프로덕션 환경에서 사용하고 있고 리액트 ㄹ엑트 네이티브 create react app과 같은 프로젝트에 포함되 어있다. yarn.lock 파일이 있는 프로젝트가 바로 얀을 사용하는 프로젝트이다.
npm install 명령과비슷하게 프로젝트 디렉터리 안에서 yarn을 실행하면 프로젝트의 모든 의존관게를 설치할 수 있다.
CHAPTER2 - 리액트를 위한 자바스크립트
2.1.1 const키워드
상수는 값을 변경할 수 없는 변수이다. 일단 선언하고 나면 상수로 선언된 변수의 값을 변경할 수는 없다.
상수에 값을 재설정 하는것은 불가능하다. 따라서 상수 값을 변경하려고 하면 콘솔 오류가 발생한다.
2.1.2 let키워드
let 키워드를 사용하면 변수의 영역을 코드 블록 안으로 한정시킬 수 있다. let 을 사용하면 블록 안에서 글로벌 변수를 보호할 수 있다.
// ES6 let을 쓰면 구문적 변수 영역 규칙을
// 적용할 수 있다
var topic = "자바스크립트"
if (topic) {
let topic = "리액트"
console.log('블록', topic)
}
console.log('글로벌', topic)
2.1.3 템프릿문자열.
템프릿 문자열을 문자열 연결 대신 사용할 수 있다. 템플릿 문자열을 사용하면 문자열 중간에 변수를 삽입할 수도 있다.
const lastName = "Oh"
const middleName = "현석"
const firstName = "Frank"
// ES6 템플릿 문자열
console.log(`${lastName}, ${firstName} ${middleName}`) // Oh,현석,Frank
2.2 함수 만들기
2.2.1 함수 선언
function logCompliment () {
console.lof("잘했ㅁ어요!")
}
logCompliment();
2.2.2.함수 표현식
const logCompliment = function (){
console.log("잘했어");
};
logCompliment()
차이점은 함수 선언은 호이스팅 되지만 함수 표현식은 그렇지 않다는 점이다 .
2.2.3 디폴트 파라미터
함수를 호출하면서 인자 값을 지정하지 않으면 디폴트 값이 쓰인다.
function logActivity(name="오성원", activity="테니스") {
console.log( `${name}은 ${activity}를 좋아합니다.` )
}
logActivity()
함수를 호출하면서 아무 인자도 지정하지 않아도 디폴트 값을 사용해 함수가 정상적으로 실행된다 . 문자열 뿐만 아니라 어떤 타입의 값이라도 디폴트 값으로 사용할 수 있다.
<디폴트 파라미터에 객체 사용 >
var defaultPerson = {
name: {
first: "성원",
last: "오"
},
favActivity: "테니스"
}
function logActivity(p=defaultPerson) {
console.log(`${p.name.first}은(는) ${p.favActivity}를 좋아합니다.`)
}
logActivity()
2.2.4 화살표 함수
화살표 함수를 사용하면 function 키워드 없이도 함수를 만들 수 있다. 화살표 함수는 return 을 사용하지 않아도 식을 계산한 값이 자동으로 반환된다.
var lordify = function(firstname) {
return `켄터베리의 ${firstname}`
}
console.log( lordify("오성원") )
console.log( lordify("오정원") )
var lordify = firstname => `캔터베리의 ${firstname}`
console.log( lordify("오성원") )
console.log( lordify("오정원") )
<if문이 포함된 화살표 함수>
결과를 계산하기 위해 여러줄을 사용해야 한다면 중괄호로 함수 본문 전체를 둘러싸야 한다.
var lordify = function(firstName, land) {
if (!firstName) {
throw new Error('lordify에 이름을 넘겨야 합니다.')
}
if (!land) {
throw new Error('영주에게는 영지가 있어야 합니다.')
}
return `${land}의 ${firstName}`
}
console.log( lordify("이계영", "멜버른") )
console.log( lordify("오현석") )
<화살표 함수와 영역>
일반함수는 this를 새로 바인딩 한다. 예를 들어 다음에서 this 는 gangwon 객체가 아닌 그 어떤것이다.
var gangwon = {
resorts: ["Kirkwood","Squaw","Alpine","Heavenly","Northstar"],
print: function(delay=1000) {
setTimeout(function() {
console.log(this.resorts.join(","))
}, delay)
}
}
gangwon.print()
이경우는 this가 window 객체이다 . 이 문제를 해결하기 위해 화살표 함수를 사용하면 this의 영역이 제대로 유지된다.
var gangwon = {
resorts: ["용평","평창","강촌","강릉","홍천"],
print: function(delay=1000) {
setTimeout(
() => console.log(this.resorts.join(",")),
delay
)
}
}
gangwon.print() // 용평 ,평창 ,강촌 ,강릉 ,홍천
print 프로퍼티를 화살표 함수로 바꾸면 this가 window 객체가 된다는 것을 의미한다 .
// 화살표 함수를 너무 많이 사용함. this가 window를 가리킴
var gangwon = {
resorts: ["용평","평창","강촌","강릉","홍천"],
print: (delay=1000) => {
setTimeout(() => {
console.log(this.resorts.join(","))
}, delay)
}
}
gangwon.print()
2.3 자바스크립트 컴파일 하기
새로운 자바스크립트 기능이 제안되고 호응을 얻으면 커뮤니티 사람들은 모든 브라우저에서 이 기능을 사용하고 싶어한다. 새로운 기능이 제대로 작동하도록 보장하는 유일한 방법은 브라우저에서 코드를 실행하기 전에 더 호환성이 높은 코드로 변환하는 것이다 . 이런 변환을 컴파일링 이라고 한다 . 가장유명한 자바스크립트 컴파일링 도구로는 바벨이있다 .
// 구조분해는 (바벨 없이) 작동하지 않는다 |
const tahoe = {
type: "lake",
name: "tahoe",
state: "california"
}
const {name, state} = tahoe
const tahoeCity = {
...tahoe,
type: "city"
}
console.log(tahoeCity.type, state)
2.4 객체와 배열
2.4.1 구조 분해를 사용한 대입
구조분해를 사용하면 객체 안에 있는 필드 값을 원하는 변수에 대입할 수 있다.
// 객체 구조분해
var sandwich = {
bread: "더치 크런치",
meat: "참치",
cheese: "스위스",
toppings: ["상추", "토마토", "머스타드"]
}
var {bread, meat} = sandwich
console.log(bread, meat)
bread = "마늘"
meat = "칠면조"
console.log(bread,meat)
console.log(sandwich.bread, sandwich.meat)
객체를 분해해서 함수의 인자로 넘길 수도 있다.
// 객체를 인자로 받는 함수
var lordify = regularPerson => {
console.log(`캔터베리의 ${regularPerson.firstname}`)
}
var regularPerson = {
firstname: "현석",
lastname: "오"
}
lordify(regularPerson)
객체의 필드에 접근하기 위해 점(.) 과 필드 이름을 사용하는 대신, regularPerson에서 필요한 값을 구조분해로 가져올 수있다.
// 객체 인자 구조분해
var lordify = ({firstname}) =>
console.log(`캔터베리의 ${firstname}`)
var regularPerson = {
firstname: "현석",
lastname: "오"
}
lordify(regularPerson)
배우자의 이름도 캔터베리의 영주로 만들고 싶다면 함수에 있는 구조분해 인수를 약간만 조정해 주면된다
const lordify = ({ spouse: { firstname } }) => {
console.log(`켄터베리의 ${firstname}`);
};
lordify(regularPerson) ;
클론과 내포된 중괄호를 사용해 fistNname을 spouse 객체로 부터 구조분해 할 수있다.
2.4.2 배열 구조 분해하기
// 배열 구조분해
var [firstResort] = ["용평","평창","강촌"]
console.log(firstResort)
불필요한 값을 콤마(,)를 사용해 생략하는 리스트 매칭을 사용할 수도있다. 변수에 대입하지 않고 무시하고 싶은 원소의 위치에 콤마를 넣으면 리스트 매칭을 사용하는 것이다 .
// 배열 구조 분해(다른 예)
var [,,thirdResort] = ["용평","평창","강촌"]
console.log(thirdResort)
2.4.3 객체 리터럴 개션
객체 리터럴 개선은 구조분해의 반대라 할 수 있다 . 또한 구조를 다시 만들어내는 과정 또는 내용을 한데 묶는 과정이라 할수 있다 . 또한 현재 영역에 있는 변수를 객체의 필드로 묶을 수 있다.
// 객체 리터럴 개선
var name = "탈락"
var elevation = 9738
var funHike = { name,elevation }
console.log(funHike)
객체 리터럴 개선 또는 객체 재구축을 통ㅎ ㅐ객체 메서드를 만드는 것도 가능하다.
// 함수를 포함하는 객체 리터럴 개선
var name = "탈락"
var elevation = 9738
var print = function() {
console.log(`${this.name} 산의 높이는 ${this.elevation}피트입니다.`)
}
var funHike = { name,elevation,print }
funHike.print()
객체 메서드를 정이할 땐 더이상 function 키워드를 사용하지 않아 된다 .
(옛날 방식)
// 예전 방식의 객체 리터럴
var name = "Léo Taillefer"
var sound = "Kahh"
var skier = {
name: name,
sound: sound,
powderYell: function() {
var yell = this.sound.toUpperCase()
console.log(`${yell} ${yell} ${yell}!!!`)
},
speed: function(mph) {
this.speed = mph
console.log('속력(mph):', mph)
}
}
skier.powderYell()
skier.speed("엉덩이에 불날 것 같은")
console.log(JSON.stringify(skier))
(새로운 방식)
// 객체 리터럴 개선
var name = "Julia Mancuso"
var sound = "go fast"
const skier = {
name,
sound,
powderYell() {
let yell = this.sound.toUpperCase()
console.log(`${yell} ${yell} ${yell}!!!`)
},
speed(mph) {
this.speed = mph
console.log('속력(mph):', mph)
}
}
skier.powderYell()
skier.speed(350)
console.log(JSON.stringify(skier))
출격값 =>
KAHH KAHH KAHH!!!
VM130:13 속력(mph): 엉덩이에 불날 것 같은
VM134:3 {"name":"Léo Taillefer","sound":"Kahh","speed":"엉덩이에 불날 것 같은"}
2.4.4 스프레드 연산자
스프레트 연산자는 3개의 점 (...)으로 이뤄진 여난자로 몇가지 다른 역할을 담당 한다.첫번째 스프레드 연산자를 사용해 배열의 내용을 조합할 수 있다. 예를 들어 두 배열이 있다면, 두배열의 모든 원소가 들어간 세번째 배열을 만들 수 있다.
var peaks = ["대청봉", "중청봉", "소청봉"]
var canyons = ["천불동계곡", "가야동계곡"]
var seoraksan = [...peaks, ...canyons]
console.log(seoraksan.join(', ')) // 대청봉,중청봉,소청봉,천불동계곡,가야동계곡
스프레드 연산자를 사용하면 원본 배열을 뒤집지 않고 복사본을 만들어서 뒤집을 수 있다.
또한 스프레드 연산자를 사용해 배열의 나머지 원소들을 얻을 수도 있다.
// 스프레드 연산자와 구조분해를 함께 사용
var lakes = ["경포호", "화진포", "송지호", "청초호"]
var [first, ...rest] = lakes
console.log(rest.join(", "))
세점 (...) 구문을 사용해 함수의 인자를 배열로 모을 수 있다.이런식으로 함수 파라미터 정의에서 스프레드 연산자가 쓰일 때는 레스트 파라미터라고 부른다 .
// 스프레드 연산자로 인자를 배열로 바꾸기
// 스프레드 연산자로 인자 중 일부를 배열로 받기
function directions(...args) {
var [start, ...remaining] = args
var [finish, ...stops] = remaining.reverse()
console.log(`${args.length} 도시를 운행합니다.`)
console.log(`${start}에서 출발합니다.`)
console.log(`목적지는 ${finish}입니다.`)
console.log(`중간에 ${stops.length}군데 들립니다.`)
}
directions("서울","수원","천안","대전","대구","부산")
//6 도시를 운행합니다.
VM207:6 서울에서 출발합니다.
VM207:7 목적지는 부산입니다.
VM207:8 중간에 4군데 들립니다.
directions 함수는 스프레드 연산자를 사용해 인자를 받는다 .
// 객체에 대한 스프레드 연산자
var morning = {
breakfast: "미역국",
lunch: "삼치구이와 보리밥"
}
var dinner = "스테이크 정식"
var backpackingMeals = {
...morning,
dinner
}
console.log(backpackingMeals)
//{breakfast: '미역국', lunch: '삼치구이와 보리밥', dinner: '스테이크 정식'}
breakfast
:
"미역국"
dinner
:
"스테이크 정식"
lunch
:
"삼치구이와 보리밥"
2.5 비동기 자바스크립트
지금까지 살펴본 코드 예제는 모두 동기적이었다 . 동기적인 자바스크립트 코드를 작성할 때는 일련의 명령이 순서대로 실행된다. 비동기 처리를 쉽게 할수있는 방법에 대해 살펴 보자 .
2.5.1 단순한 프로미스와 fetch
프라미스는 자바스크립트에서 비동기적인 동작을 잘 처리할 수 있게 해준다. 대기중인 프라미스는 데이터가 도착하기 전의 상태를 표현한다. .then() 이라는 함수를 대기 중인 프라미스는 데이터가 도착하기 전의 상태를 표현한다.
.then()이라는 함수를 대기 중인 프라미스에 연쇄 호출해야 한다. 이 함수는 콜백 함수를 인수로 받으며 , 바로 앞에 있는 프라미스(연산)이 성공하면 콜백이 호출된다.
다른말로 하면 fetch()는 데이터를 받아오고 , then()은 데이터가 도착하면 그 데이터를 가지고 다른일을 한다.
const getFakeMembers = count => new Promise((resolves, rejects) => {
const api = `https://api.randomuser.me/?nat=US&results=${count}`
const request = new XMLHttpRequest()
request.open('GET', api)
request.onload = () =>
(request.status === 200) ?
resolves(JSON.parse(request.response).results) :
reject(Error(request.statusText))
request.onerror = (err) => rejects(err)
request.send()
})
getFakeMembers(5).then(
members => console.log(members),
err => console.error(
new Error("randomuser.me에서 멤버를 가져올 수 없습니다."))
)
'독서 > 모던자바스크립트&러닝리액트' 카테고리의 다른 글
러닝 리액트 2판 정리 (3장) (0) | 2022.09.27 |
---|---|
모던자바스크립트 deepdive 정리 (43장) -수정필요 (0) | 2022.06.23 |
모던자바스크립트 deepdive 정리 (9~11장) (0) | 2022.05.22 |
모던자바스크립트 deep dive 정리(1~8) (0) | 2022.05.21 |