본문 바로가기
source-code/React

리액트를 다루는 기술 _ 1장, 2장, 3장

by mattew4483 2021. 3. 9.
728x90
반응형

약 1주일 간 JavaScript 복습 및 실습을 완료한 후... 다시 펴보는 책!

참말로 두껍기도 하다! 함께 차근차근 따라 해 볼 예정.


1장. 리액트 시작

1-1) 작업 환경 설정

시작하려고 신나게 create-react-app을 쳤더니...

띠요용. 업데이트로 인한 버전 문제인 듯싶다.

 

npm uninstall -g로 제거해준 후, 다시 설치하면 해결!

 

다시 npm create react-app을 통해 React 앱을 생성해준다.

 

이후 cd를 통해 생성한 앱에 들어간 후, npm start를 해주면...!

여전히 잘 뜬다! 1장 끝!(?)

 

2장. JSX

2-1) JSX 이해하기

생성한 React App에서 src/App.js 파일을 열어보자.

App.js

여전히 희한하게도 생겼다.

분명 생긴 건 JS인데... 또 안의 요소는 HTML이고... → 요놈이 바로 JSX!

 

만일 JSX 코드를 작성하는 것이 아니라면 컴포넌트를 렌더링 할 때마다

이런 식으로 작성을 해야 했을 테다. JSX 만세!

 

물론 이 녀석은 공식적인 JS 문법은 아니다.

하지만 보기 쉽고 익숙할 뿐만 아니라,

생성된 컴포넌트를 다른 파일에서 HTML 태그처럼 사용할 수 있다는 장점이 있다 ← 이게 무슨 말?

 

index.js

src의 index.js 파일에 들어가 보면...

방금 생성한 App이라는 컴포넌트를 흔한 HTML 태그처럼 사용해뒀다. 와우!

 

여기서 ReactDom.render란?

요 녀석은 컴포넌트를 페이지에 렌더링 하는 역할을 하며, react-dom 모듈을 불러와 사용할 수 있다.

함수의 첫 번째 파라미터에는 페이지에 렌더링 할 내용을 작성하고(JSX 형태로),

두 번째 파라미터에는 해당 JSX를 렌더링 할 document의 내부 요소를 설정한다. 

즉 여기서는 id가 root인 요소 안에 렌더링을 하게끔 설정한 것!(얘는 public/index.html에 존재한다)

 

2-2) JSX 문법

1. 감싸인 문법

컴포넌트에 여러 요소가 있다면, 반드시 부모 요소 하나로 감싸야한다.

왜? → 컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙 때문.

그 규칙은 또 왜? Virtual DOM(실제 DOM의 사본)에서 컴포넌트 변화를 감지해 낼 때 효율적으로 비교하기 위해!

 

App.js

물론 반드시 부모 요소를 div로 설정할 필요는 없다.

React v16 이상부터는 Fragment라는 기능이 도입되어 사용이 가능.

그리고 이 fragment는 <> </>로 표현할 수도 있다.

 

2. JavaScript 표현식

당연히 JSX 내에서는 JS 표현식을 사용할 수 있다.

App.js

이런 식으로!

 

3. If문 대신 조건부 연산자

JSX 내부 JS 표현식에서 if문은 사용할 수 없다.

따라서 조건에 따라 다른 내용을 렌더링 할 때는 → JSX 밖에서 미리 if문을 사용하거나, 삼항 연산자를 사용!

App.js

현제 name = "lee"이므로 브라우저에는 '안녕!' 이 뜰 테다.

 

4.  AND 연산자(&&)를 사용한 조건부 렌더링

조건을 만족하지 않을 때는 아무것도 렌더링 하지 않으려면?

App.js

&& 연산자를 사용하면 된다 → React에서 false를 렌더링 할 때는 null처럼 아무것도 나타나지 않으므로!

 

5. undefined를 렌더링 하지 않기

React 컴포넌트에서는 함수에서 undefined만 반환해 렌더링 하면 오류가 발생한다.

반면 JSX 내부(즉 return() 내부)에서 undefined를 렌더링 하는 건 가능!

App.js

이렇게 작성하면 '리액트'가 렌더링 된다 이 말씀.

 

6. 인라인 스타일링

DOM 요소에 스타일 적용 시, JS처럼 카멜 표기법으로 작성하면 된다!

App.js

요로코롬!

그런데 왜 style={{ }} ← 이렇게 괄호가 2개 들어간 걸까?

간단히 말해 바깥쪽 {}는 JSX 속 HTML 문법, 안쪽 {}는 CSS 문법이라 생각하면 된다.

즉 원래는 const style = {backgroundColor:'black'} / <div style={style}>로 작성되어 있는 것!

 

7. class 대신 className

src/App.css

App.js

App.css 파일에 원하는 스타일을 지정해주자.

여기서 react란 이름은? 당연히 class명이겠지!

 

App.js

App.js

따란. 하지만 React에서는 class 대신 className으로 설정해줘야 한다!

 

8. 꼭 닫아야 하는 태그

HTML에서는 br, input  등의 태그는 <input>과 같은 형태로도 사용이 가능하다.

하지만 React에서는? 이러한 태그들도 <input></input>과 같은 형태로 꼭 닫아야 한다!

App.js

self-closing 태그는 태그 사이 별도의 내용이 들어가지 않는 경우에 위처럼 작성할 수 있다.

이는 태그를 선언함과 동시에 닫은 것!

 

3장. 컴포넌트

컴포넌트는? 단순한 템플릿 이상의 기능을 수행!

주어진 데이터에 맞춘 UI를 만들거나, 컴포넌트에 변화가 일어날 때 주어진 작업을 수행하거나,

임의 메서드를 만들어 특별한 기능을 붙여주는 등 다양한 용도로 사용할 수 있다.

 

3-1) 클래스형 컴포넌트

컴포넌트를 선언하는 방식은 → 함수형 컴포넌트와 클래스형 컴포넌트! django의 view가 생각나는 순간

App.js

아까와 똑같은 내용이지만 함수형에서 클래스형으로 바꿔 작성한 컴포넌트.

클래스형 컴포넌트에서는 render 함수가 꼭 있어야 하고, 그 안에서 보여줄 JSX를 반환해야 한다.

 

그렇다면 둘의 차이는?

클래스형 컴포넌트의 경우 state 및 라이프사이클 기능을 사용할 수 있으며, 임의 메서드를 정의할 수 있다는 점.

하지만 React v16.8 업데이트 이후 Hooks라는 기능이 도입되면서... 함수형 컴포넌트도 이러한 부분이 해결되었다!

(공식 문서에서도 컴포넌트를 새로 작성할 때 함수형 컴포넌트와 Hooks를 사용하도록 권장 중)

 

3-2) 컴포넌트 생성하기

첫 번째 컴포넌트를 만들기 위해..!

파일 생성 → 코드 작성 → 모듈 내보내기 및 불러오기 의 단계를 거칠 예정.

1. 파일 생성

src 폴더 내 MyComponent.js라는 파일을 만들기!

 

2. 코드 작성하기

MyComponent.js

짜잔. 함수형으로 MyComponent란 이름의 컴포넌트를 만들었다.

 

그런데 생긴 것이 영... 이전 App.js와 다르다?

차이점은 바로 화살표 함수가 사용된 것!

BlackDog 함수는 검둥이를, WhiteDog 함수는 흰둥이를 return 한다. 어째서?

그 이유는 두 함수가 가리키고 있는 this 값이 다르기 때문!

일반 함수는 자신이 종속된 객체를 this로 가리키며, 화살표 함수는 자신이 종속된 인스턴스를 가리킨다.

BlackDog 함수의 this는 return 다음의 {}를, WhiteDog 함수의 this는 WhiteDog() 다음의 {}를! 맞나..?

 

3. 모듈 내보내기 및 불러오기

MyComponent.js

지금껏 각 파일들 제일 밑에 있던 요 녀석의 정체!

바로 해당 모듈을 export 해주는 코드 되시겠다.

이를 통해 다른 파일에서 이 파일을 import 할 때, 위에서 선언한 MyComponent 클래스를 불러오도록!

 

App.js

이렇게 생성한 파일을 App.js에서 불러와 사용할 수 있다.

 

잘 적용되는 모습!

 

3-3) props

props는 properties를 줄인 표현으로, 컴포넌트의 속성을 설정할 때 사용하는 요소!

props 값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서 설정할 수 있다.

 

1. props 설정하기

MyComponent.js

우선 MyComponent에서 name이라는 props를 렌더링 하도록!

(화살표 함수에서 파라미터 값이 하나일 때는 ()를 생략할 수 있다)

 

이때 props 값은 컴포넌트 함수의 파라미터로 받아와서 사용할 수 있으며,

렌더링 시 JSX 내부에서 {}로 감싸주면 된다.

 

App.js

App 컴포넌트에서 MyComponent의 props를 지정해주자!

 

쨔잔. 역시나 성공적으로 반영된 모습.

 

2. 기본값 설정하기

MyComponent.js

props 값을 따로 지정하지 않았을 때 보여줄 기본값을 설정해줄 수도 있다.

MyComponent.js에서 defaultProps를 사용해 설정 가능!

 

3. children

children은 컴포넌트 태그 사이의 내용을 보여주는 props!

 

App.js

우선 App 컴포넌트 태그 사이에 내용을 적어주자. 

이 녀석을 렌더링 하기 위해서는? (그냥 이렇게 적으면 MyComponent만 뜰뿐이다)

 

MyComponent.js

쨔잔. props.children을 통해 태그 사이 내용에 접근할 수 있다.

만만세!

 

4. props 내부 값 추출하기

현재 MyComponent에서 props를 조회할 때마다 props.이라는 키워드를 붙여주고 있다.

DRY... DRY... → ES6의 비구조화 할당 문법을 통해 내부 값을 바로 추출할 수 있다!

 

MyComponent.js

MyComponent는 다음과 같이 수정할 수 있다!

이렇게 객체에서 값을 추출하는 방식을 비구조화 할당(이름이 참 어렵군)이라고 부른다.

 

이는 함수의 파라미터 부분에서도 사용할 수 있는데,

만약 함수의 파라미터가 객체라면 그 값을 바로 비구조화해서 사용할 수 있다.

 

즉 이런 식으로!

이렇게만 보면 props와 연관이 있는 건가 싶지만(마치 그냥 함수의 인자로 넘겨준 녀석들을 사용하는 모양새),

비구조화 할당 문법이 사용되었음을 기억해두자!

 

5. propTypes를 통한 props 검증

컴포넌트의 필수 props를 지정하거나, props의 타입을 지정할 때는 propTypes이란 녀석을 사용한다.

또한 array, bool, func, number, object, string 등 익숙한 종류의 녀석들을 설정 가능!

 

MyComponent.js

쨘. 우선 PropsTypes를 import 한 후, 컴포넌트의 propsTypes를 지정해준다.

이 경우 name 값은 무조건 문자열 형태로 전달해야 함을 의미!

따라서 이때 App 컴포넌트에서 name을 문자열이 아닌 값으로 지정할 경우, console에서 에러 메시지를 출력한다.

 

Mycomponent.js

만약 propTypes를 필수로 지정하고 싶다면? 이렇게 isRequired를 붙여주면 된다!

 

3-4) state

state는? 컴포넌트 내부에서 바뀔 수 있는 값을 의미한다.

 

그럼 props는? 얘는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값이며,

컴포넌트 자신은 해당 props를 읽기 전용으로만 사용할 수 있다. (즉 props 변경은 부모 컴포넌트에서만 가능)

 

함수형 컴포넌트에서는 useState라는 함수를 통해 state를 사용한다.

이 과정에서 사용되는 것이 바로 Hooks!

Hooks의 종류는 다양하지만 일단 지금은 useState만 사용해보자.

 

1. 배열 비구조화 할당

아까 들어본 듯한 단어다! 아까 배운 객체 비구조화 할당과 비슷한 개념.

즉 배열 안에 들어 있는 값을 쉽게 추출할 수 있도록 해주는 문법 되시겠다.

 

array 안에 있는 값을 one과 two에 담아주는 코드인데...

배열 비구조화 할당을 사용한 오른쪽 코드가 훨씬 깔끔하다!

 

2. useState 사용하기

우선 src 폴더 내에 Say.js 파일을 생성하자.

Say.js

useState 함수가 사용되었는데...

이 함수의 인자에는 상태의 초깃값을 넣어준다! 이 때 값의 형태는 자유(숫자, 문자열, 객체 등등...)

 

함수를 호출하면 배열이 반환되는데,

배열의 첫 번째 원소는 현재 상태, 두 번째 원소는 상태를 바꾸어 주는 함수다.

(두 번째 함수를 Setter 함수라 부른다)

반환된 배열을 비구조화 할당을 통해 이름을 자유롭게 정해 줄 수 있는 것!

 

App.js

App.js에서 Say 컴포넌트를 렌더링 하면...!

 

http://localhost:3000/

입장 버튼을 누르면 안녕하세요가, 퇴장 버튼을 누르면 안녕히 가세요가 뜬다.

 

App.js

useState는 한 컴포넌트에서 여러 번 사용해도 상관없다!

위와 같이 코드를 작성하면...

http://localhost:3000/

엄청 단순한 기능! 하지만 JS만으로 이를 구현한다고 생각하면... 흐아.

 

정리하자면, props와 state 둘 다 컴포넌트에서 사용하거나 렌더링 할 데이터를 담고 있다.

그러나 props는 부모 컴포넌트가 설정하고,

state는 컴포넌트 자체적으로 지닌 값으로 내부에서 값을 수정할 수 있다는 차이를 같는다!

 

또한 props를 사용한다고 해서 값이 무조건 고정적인 것은 아니다!

부모 컴포넌트의 state를 자식 컴포넌트의 props로 전달하고,

자식 컴포넌트에서 특정 이벤트가 발생할 때

부모 컴포넌트의 메서드를 호출하는 식으로 props를 유동적으로 사용할 수도 있다.

728x90
반응형

'source-code > React' 카테고리의 다른 글

리액트를 다루는 기술 _ 6장  (0) 2021.03.09
리액트를 다루는 기술 _ 5장  (0) 2021.03.09
리액트를 다루는 기술 _ 4장  (0) 2021.03.09
React Component, props, state 맛보기  (2) 2021.01.20
React 맛보기  (0) 2021.01.19