본문 바로가기
카테고리 없음

ㄱㄷㅁㅊㅅ

by 학습하는 청년 2023. 6. 20.

JSX 문법

JSX는 자바스크립트로 HTML과 비슷한 문법을 사용할 수 있도록 만들어주는 자바스크립트의 확장 문법

JSX는 화면과 동작을 좀 더 직관적으로 개발할 수 있는 편리한 문법이지만 그만큼 꼭 지켜야 할 규칙들도 있습니다.

HTML과 다른 속성명

1. 속성명은 카멜 케이스로 작성하기!

JSX 문법에서도 태그에 속성을 지정해 줄 수 있습니다. 단, 여러 단어가 조합된 몇몇 속성들을 사용할 때는 반드시 카멜 케이스(Camel Case)로 작성해야 합니다.

 

2. 자바스크립트 예약어와 같은 속성명은 사용할 수 없다!

JSX 문법도 결국은 자바스크립트 문법이기 때문에, for나 class처럼 자바스크립트의 문법에 해당하는 예약어와 똑같은 이름의 속성명은 사용할 수 없습니다. 그래서 HTML의 for의 경우에는 자바스크립트의 반복문 키워드 for와 겹치기 때문에 htmlFor로, HTML의 class 속성도 자바스크립트의 클래스 키워드 class와 겹치기 때문에 className으로 작성해 주어야 합니다.

React 공식 문서 - 어트리뷰트의 차이

 

반드시 하나의 요소로 감싸기 - Fragment

JSX 문법을 활용할 때는 반드시 하나의 요소로 감싸주어야 합니다.

Fragment로 감싸주면 의미 없는 부모 태그를 만들지 않아도 여러 요소를 작성할 수 있습니다.

 

자바스크립트 표현식 넣기

JSX 문법에서 중괄호({})를 활용하면 자바스크립트 표현식을 넣을 수 있습니다.

이런 부분들을 잘 활용하면, 아래 코드처럼 중괄호 안에서 문자열을 조합할 수도 있고 변수에 이미지 주소를 할당해서 img 태그의 src 속성값을 전달해 줄 수도 있고, 이벤트 핸들러를 좀 더 편리하게 등록할 수도 있습니다.

 

단, JSX 문법에서 중괄호는 자바스크립트 표현식을 다룰 때 활용하기 때문에, 중괄호 안에서 for, if문 등의 문장은 다룰 수 없다는 점은 꼭 기억해 주세요. 그런데도 만약 JSX 문법을 활용할 때 조건문이 꼭 필요하다면 조건 연산자를, 반복문이 꼭 필요하다면 배열의 반복 메소드를 활용해 볼 수는 있겠죠?

 

===

리액트 엘리먼트

JSX 문법으로 작성한 요소는 결과적으로 자바스크립트 객체가 됩니다.

이런 객체를 리액트 엘리먼트라고 부르는데요.

이 리액트 엘리먼트를 ReactDOM.render 함수의 아규먼트로 전달하게 되면, 리액트가 객체 형태의 값을 해석해서 HTML 형태로 브라우저에 띄워주는 것이죠.

리액트 엘리먼트는 리액트로 화면을 그려내는데 가장 기본적인 요소입니다.

 

리액트 컴포넌트

리액트 컴포넌트는 리액트 엘리먼트를 조금 더 자유롭게 다루기 위한 하나의 문법입니다.

컴포넌트를 만드는 가장 간단한 방법은 자바스크립트의 함수를 활용하는 건데요.

 

한 가지 주의해야 할 부분은, 리액트 컴포넌트의 이름은 반드시 첫 글자를 대문자로 작성해야 한다는 것입니다. 컴포넌트 이름의 첫 글자가 소문자라면 오류가 발생하니깐 꼭 주의해 주세요!

 

==

Props

JSX 문법에서 컴포넌트를 작성할 때 컴포넌트에도 속성을 지정할 수 있는데요. 리액트에서 이렇게 컴포넌트에 지정한 속성들을 Props라고 부릅니다.

Props는 Properties의 약자인데요. 컴포넌트에 속성을 지정해주면 각 속성이 하나의 객체로 모여서 컴포넌트를 정의한 함수의 첫 번째 파라미터로 전달됩니다.

 

Children

props에는 children이라는 조금 특별한 프로퍼티(prop, 프롭)가 있습니다.

JSX 문법으로 컴포넌트를 작성할 때 컴포넌트를 단일 태그가 아니라 여는 태그와 닫는 태그의 형태로 작성하면, 그 안에 작성된 코드가 바로 이 children 값에 담기게 됩니다.

 

그래서 JSX 문법으로 컴포넌트를 작성할 때 어떤 정보를 전달할 때는 일반적인 props의 속성값을 주로 활용하고, 화면에 보여질 모습을 조금 더 직관적인 코드로 작성하고자 할 때 children 값을 활용할 수가 있습니다.

참고로 이 children을 활용하면 단순히 텍스트만 작성하는 걸 넘어서 컴포넌트 안에 컴포넌트를 작성할 수도 있고, 컴포넌트 안에 복잡한 태그들을 더 작성할 수도 있으니깐 이 값을 어떻게 활용하면 좋을지 여러분도 한번 고민해 보시면 좋을 것 같습니다!

 

===

State

state는 리액트에서 화면을 그려내는 데 굉장히 중요한 역할을 합니다.

State라는 단어는 한국어로 '상태'라는 뜻이 있는데요. 리액트에서의 state도 그 의미가 다르지 않습니다. 상태가 바뀔 때마다 화면을 새롭게 그려내는 방식으로 동작을 하는 것이죠.

리액트에서 state를 만들고, state를 바꾸기 위해서는 일단 useState라는 함수를 활용해야 합니다.

 

첫 번째 요소가 바로 state이고, 두 번째 요소가 이 state를 바꾸는 setter 함수인데요.

 

state는 변수에 새로운 값을 할당하는 방식으로 변경하는 것이 아니라 이 setter 함수를 활용해야 하는데요. setter 함수는 호출할 때 전달하는 아규먼트 값으로 state 값을 변경해 줍니다.

 

 

참조형 State

자바스크립트의 자료형은 크게 기본형(Primitive type)과 참조형(Reference type)로 나눌 수 있다는 사실, 모두 알고 계시죠?

특히 참조형 값들은 조금 독특한 특성을 가지고 있어서 변수로 다룰 때도 조금 주의해야 할 부분들이 있었는데요. state를 활용할 때도 마찬가지입니다!

 

참조형 state를 활용할 때는 반드시 새로운 참조형 값을 만들어 state를 변경해야 합니다.

가장 간단한 방법은 Spread 문법(...) 을 활용하는 것이겠죠?

 

HandButton 컴포넌트에서 HandIcon 컴포넌트에 CSS 스타일을 적용하고 있는데요

이렇게 하면 좋은 점은

HandIcon을 다양한 곳에서 사용하더라도 HandIcon에서 모든 경우의 수를 처리하는 게 아니라

HandButton, 예를들면 다른 어떤 MyComponent 같은 데서 HandIcon을 사용할 때도

CSS 클래스를 사용하는 쪽(HandButton이랑 MyComponent 같이 HandIcon을 사용하는 쪽)에서 클래스네임을 집어넣는 식으로 하면

컴포넌트의 사용성이 조아져요!

 

편리하게 클래스네임을 쓰는 방법

classnames라는 라이브러리입니다. 클래스네임에만 집중할 수 있어 훨씬 읽기 편해집니다. 이렇게 적절한 라이브러리를 쓰면 개발 생산성이 굉장히 좋아지죠.

classnames 은 NPM이라는 프로그램을 통해 설치할 수 있습니다.

 

NPM classnames 패키지: https://www.npmjs.com/package/classnames

 

 

====

명령어 복습하기

터미널에서 원하는 디렉토리에 들어가서 npm init react-app .를 입력하면 현재 디렉토리에 리액트 프로젝트를 생성합니다.

터미널에서 npm run start를 입력하면 개발 모드 서버가 실행됩니다.

서버가 실행 중인 터미널에서 ctrl + c를 입력하면 서버가 종료됩니다.

터미널에서 npm run build를 입력하면 빌드를 시작합니다.

터미널에서 npx serve build를 입력하면 serve 프로그램을 다운 받고 build 폴더에서 서버가 실행됩니다.

 

 

====

기본 submit 동작 막기

HTML 폼의 기본 동작은 submit 타입의 버튼을 눌렀을 때 페이지를 이동하는 건데요.

이벤트 객체의 preventDefault 를 사용하면 이 동작을 막을 수 있었습니다.

 

====

제어 컴포넌트

인풋 태그의 value 속성을 지정하고 사용하는 컴포넌트입니다.

리액트에서 인풋의 값을 제어하는 경우로 리액트에서 지정한 값과 실제 인풋 value 의 값이 항상 같습니다.

이렇게 하면 값을 예측하기가 쉽고 인풋에 쓰는 값을 여러 군데서 쉽게 바꿀 수 있다는 장점이 있어서 리액트에서 권장하는 방법인데요.

이때 State냐 Prop이냐는 중요하지 않고, 리액트로 value 를 지정한다는 것이 핵심입니다.

 

비제어 컴포넌트

인풋 태그의 value 속성을 리액트에서 지정하지 않고 사용하는 컴포넌트입니다.

 

제어 컴포넌트랑 비제어 컴포넌트 모두 쓸 수 있는 경우라면

제어 컴포넌트를 사용하는 걸 추천드립니다!

하지만 반드시 비제어 컴포넌트로 만들어야만 하는 경우가 있는데요, 대표적으로 파일을 선택하는 인풋이 그렇습니다.

 

====

사이드 이펙트(Side Effect)란?

사이드 이펙트는 한국어로는 '부작용'이라는 뜻입니다.

일상생활에서는 '약의 부작용'처럼 사용하는 단어인데요.

예를 들면 감기약을 먹었을 때

감기 증상은 없어졌지만 (작용)

피부가 붉게 올라오면 (부작용)

이 약에는 부작용이 있다고 할 수 있죠.

일상생활에서는 주로 안 좋은 것들을 부작용이라고 부르지만

프로그래밍에선 말 그대로 외부에 부수적인 작용을 하는 걸 말하는데요.

 

사이드 이펙트와 useEffect

useEffect 는 리액트 컴포넌트 함수 안에서

사이드 이펙트를 실행하고 싶을 때 사용하는 함수입니다.

예를들면 DOM 노드를 직접 변경한다거나,

브라우저에 데이터를 저장하고,

네트워크 리퀘스트를 보내는 것처럼 말이죠.

주로 리액트 외부에 있는 데이터나 상태를 변경할 때 사용하는데요.

 

useEffect를 쓰면 좋은 경우

useEffect 는 쉽게 말해서 '동기화'에 쓰면 유용한 경우가 많은데요.

여기서 동기화는 컴포넌트 안에 데이터와 리액트 바깥에 있는 데이터를 일치시키는 걸 말합니다.

 

===

Hook의 규칙

  • 반드시 리액트 컴포넌트 함수(Functional Component) 안에서 사용해야 함
  • 컴포넌트 함수의 최상위에서만 사용 (조건문, 반복문 안에서 못 씀)

useState

===

exhaustive-deps 규칙

리액트에서는 Prop이나 State와 관련된 값은 되도록이면 빠짐없이 디펜던시에 추가해서

항상 최신 값으로 useEffect 나 useCallback 을 사용하도록 권장하고 있습니다.

 

useCallback으로 함수 재사용하기

디펜던시 리스트에 추가한 함수가 매번 바뀌는 문제를 해결하려면

함수를 useCallback 으로 감싸주면 됩니다.

useCallback 을 사용하면 함수를 매번 생성하는 게 아니라

리액트에다 함수를 기억해둘 수 있는데요.

이때 리액트는 useCallback 의 디펜던시 리스트 값이 바뀔 때만 함수를 새로 만들어줍니다.

이런 식으로 컴포넌트 안에서 만든 함수를 디펜던시 리스트에 사용할 때는

useCallback 훅으로 매번 함수를 새로 생성하는 걸 막을 수 있습니다.

되도록이면 파라미터를 활용하자

마지막으로 이 코드를 좀 더 개선할 방법은 없을까요?

Prop이나 State 값을 사용할 때는 이렇게 되도록이면 파라미터로 넘겨서 사용하면,

어떻게 사용되는지 코드에서 명확하게 보여줄 수 있습니다.

 

===

리액트 Context

Context는 한국어로 맥락이라는 뜻입니다.

쉽게 말해서 어떤 상황에 대한 정보를 의미하는데요.

앞에서 배운 예시처럼

'사용자가 한국어를 사용하는 상황', '사용자가 영어를 사용하는 상황' 같은 걸

여러 컴포넌트에 공유하고 싶을 때 사용합니다.

Props만으로 리액트 개발을 하다 보면

여러 곳에 쓰이는 데이터를 내려주고 싶을 때가 있는데요.

이때 컴포넌트의 단계가 많다면 여러 번 반복해서 Prop을 내려줘야 합니다.

이런 문제점을 프롭 드릴링(Prop Drilling)이라고 했죠?

Context는 프롭 드릴링을 해결하기 위해 사용하는 기능입니다.

 

===

상태 관리(State Management)

- 화면에서 사용하는 데이터를 관리하는 것

 

====

React-router : 리액트 컴포넌트로 페이지를 나누는 라이브러

Router : 리액트 라우터에서 사용하는 데이터들을 모두 갖고 있다. 현재 주소, 페이지 기록 

Link : 리액트 라우터에서 a 태그 대신 사용한다.

 

Link, Navigate, useNavigate는 언제 쓰는게 좋을까?

세 가지 모두 다 페이지를 이동할 때 쓸 수 있다는 점에서 비슷한데요.

이것들을 언제 사용하면 좋을지 예시랑 같이 한번 살펴봅시다.

Link

사용자가 클릭해서 페이지를 이동하도록 할 때 사용하면 됩니다.

하이퍼링크 텍스트나 페이지를 이동하는 버튼, 이미지 등에 사용하면 되겠죠?

대부분의 경우 Link 만으로도 충분합니다.

Navigate

특정 경로에서 렌더링 시점에 다른 페이지로 이동시키고 싶을 때 사용하면 됩니다.

예시:

  • 쇼핑몰의 회원 전용 페이지에 로그인없이 들어와서 로그인 페이지로 리다이렉트하는 경우
  • 쇼핑몰의 상품 상세 페이지에서 제품이 품절되었거나 삭제되어서 다른 페이지로 이동시키는 경우

useNavigate

특정한 코드의 실행이 끝나고 나서 페이지를 이동시키고 싶을 때 사용하면 됩니다.

예시:

  • 쇼핑몰에서 장바구니에 담기를 눌렀을 때 리퀘스트를 보내고 장바구니 페이지로 이동시키는 경우
  • 쇼핑몰에서 결제하기 버튼을 누르고 나서 모든 결제가 완료된 후에 페이지를 이동시키는 경우
  • 리다이렉트된 로그인 페이지에서 로그인을 완료한 후에 처음 진입했던 페이지로 돌아가는 경우

 

+)

react-helmet으로 페이지 제목 설정하기

===

CSR

웹 브라우저에서 자바스크립트로 HTML 페이지를 만드는 것

 

SPA

하나의 HTML 문서 안에서 자바스크립트로 여러 페이지를 보여주는 사이

댓글