02. 컴포넌트

개발자 취준생 밍키·2022년 10월 3일
0

개인공부🤓

목록 보기
11/28
post-custom-banner

컴포넌트 기본

: 블록이고, 결국 함수다
: 화면을 구성하는 하나의 단위

: 보통 html을 return하는 함수, div태그 리턴할 수도 있음

컴포넌트(함수) 코드 보는 법

영역을 나누면 보기 편함

1)
🔥 컴포넌트 밖에서 내가 필요한 파일 import
🔥 내가 만든 컴포넌트 밖으로 내보내는 export default
2)
자바스크립트 이용해서 action해야하는 경우 자바스크립트 쓸 수 있는 부분에 넣기
3)
return 기준으로 아랫부분엔 html(JSX) 작성

이름 짓기

: 컴포넌트 첫 글자는 반드시 대문자
: 폴더는 소문자로 시작하는 카멜케이스
: 컴포넌트를 만드는 파일은 대문자로 시작하는 카멜케이스

🙋🏻‍♀️클래스 컴포넌트는 무엇이고, 함수 컴포넌트와 무엇이 다른가?

부모/자식 컴포넌트

컴포넌트는 다른 컴포넌트를 품을 수 있음
부모 컴포넌트 : 다른 컴포넌트를 품음
자식 컴포넌트 : 다른 컴포넌트 안에서 품어짐

🔥 Child라는 새로운 컴포넌트를 App 컴포넌트에서 마치 HTML 태그를 쓰듯이 넣음
=> 내보내진 컴포넌트는 App -> App은 Child 컴포넌트가 자식 -> Child 컴포넌트의 실행문 실행

: 이렇게 만들어진 컴포넌트는 마치 HTML 태그를 쓰듯 렌더링할 수 있음
-> 렌더링(Rendering) : 화면에 보여지게 하다
-> JSX : 함수로 만들어진 컴포넌트를 HTML 태그 사용하듯 코드를 작성하는 방식

함수 컴포넌트

: 인수 props를 입력받고, 화면에 어떻게 표현되는지 기술하는 React 엘리먼트 반환
: 컴포넌트 쉽게 정의하는 법 -> js 함수 작성 ㅋㅋ
: 객체 인자를 받은 후 React 엘리먼트 반환 -> 유효한 React 컴포넌트

클래스 컴포넌트

: 인수 props를 입력받고, 화면에 어떻게 표현되는지 기술하는 React 엘리먼트 반환
: ES6 class 사용해서 컴포넌트 정의
: 클래스 컴포넌트는 현재 잘 쓰이지 않음

=> 위의 함수 컴포넌트와 클래스 컴포넌트는 React 입장에서 동일

컴포넌트 렌더링

: DOM 태그뿐만 아니라 사용자 정의 컴포넌트로도 나타낼 수 있음
: React가 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견
-> JSX 어트리뷰트와 자식을 사용자 정의 컴포넌트에 단일 객체로 전달

: 소문자로 시작하는 컴포넌트는 DOM 태그로 처리
: <div/>는 HTML div태그 나타냄, <Welcome />은 컴포넌트 나타내고 범위 안에 있어야함

  1. <Welcome name=“Sara”/> 엘리먼트로 root.render()를 호출
  2. React는 {name: ‘Sara’}를 props로 하여 Welcome 컴포넌트를 호출
  3. {props.name}에 ’Sara’가 들어감
  4. <h1> Hello, Sara </h1> 엘리먼트 반환
  5. React DOM은 <h1> Hello, Sara </h1> 엘리먼트와 일치하도록 DOM을 효율적으로 업데이트

컴포넌트 합성

: JSX 태그는 자식을 포함할 수 있음
: 컴포넌트는 자신의 출력에 다른 컴포넌트를 참조할 수 있음
-> 모든 세부 단계에서 동일한 추상 컴포넌트를 사용할 수 있음
: React 앱에서는 버튼, 폼, 다이얼로그, 화면 등 모든 것들이 컴포넌트로 표현

: Welcome을 여러번 렌더링하는 App 컴포넌트

🔥 보통 새 React 앱은 최상위에 단일 App 컴포넌트 가짐
(기존 앱에 React를 통합하는 경우 Button과 같은 작은 컴포넌트부터 시작해서
뷰 계층의 상단으로 올라가면서 점진적으로 작업해야할 수 있음)

✅ 엘리먼트

: React 앱의 가장 작은 단위, 컴포넌트의 구성요소
: 브라우저 DOM 엘리먼트와 달리 React 엘리먼트는 일반 객체이며 쉽게 생성 가능
: React DOM은 React 엘리먼트와 일치하도록 DOM을 업데이트

: HTML 파일에 포함된 <div> 안에 들어가는 모든 엘리먼트는 React DOM에서 관리
-> 루트 DOM 노드
: React로 구현된 앱은 일반적으로 하나의 루트 DOM 노드가 있음
: React를 기존 앱에 통합하려는 경우, 원하는만큼의 독립된 루트 DOM 노드의 존재가 가능

렌더링 된 엘리먼트 업데이트

: React 엘리먼트는 불변객체 -> 생성 후에 엘리먼트의 자식이나 속성 변경 불가
: 영화의 프레임 한개처럼 특정 시점의 UI를 보여줌
🔥 UI 업데이트 방법 : 새 엘리먼트 생성 -> root.render()로 전달

: 위 함수는 setInterval() 콜백을 이용해 초마다 root.render() 호출
🔥 React 앱은 root.render() 한번만 호출

변경된 부분만 업데이트하기

: React DOM은 해당 엘리먼트와 그 자식 엘리먼트를 이전의 엘리먼트와 비교함
: DOM을 원하는 상태로 만들기 위해 필요한 경우에만 DOM을 업데이트
ex) 매 초 전체 UI를 다시 그리도록 엘리먼트 만듦 -> React DOM은 내용이 변경된 텍스트 노드만 업데이트

🔥시간의 변화에 따라 UI가 어떻게 변화할까? <<< 특정 시점에 UI가 어떻게 보일까? -> 버그 위험 감소

✅ JSX

🔥 React에는 딱 하나의 html 파일만 존재 (public 폴더 아래에 있는 index.html)

🔥 React에서 뷰를 그리는 방법
: JSX 문법을 이용해 React 요소를 만들고 DOM에 렌더링시켜서 그림

: 기존 App.js 코드

HTML을 품은 JS === JSX

원래 .js 파일에는 HTML 태그 쓸 수 없음 ex) <h1>, <p>
-> JSX는 .js 안에서 HTML 태그같은 마크업을 넣어 뷰(UI) 작업을 편하게 해줌!

: js를 확장한 문법
: UI가 어떻게 생겨야하는지 설명하기 위해 React와 함께 사용
: 단순히 템플릿 언어가 아니라 js의 모든 기능이 포함
: React의 ‘엘리먼트(element)’를 생성
: JSX 사용이 필수는 아니지만 UI 작업과 오류 관리에 도움됨

💡 <div> ~ </div> 는 DOM 요소?
정확히는 React 요소!
리액트 돔을 구성하는건 리액트 요소! 돔을 구성하는건 돔 요소!

: React에서는 렌더링 로직이 UI 로직과 연결됨

💡UI 로직
이벤트가 처리되는 방식, 시간에 따라 state가 변하는 방식,
화면에 표시하기 위해 데이터가 준비되는 방식

: 별도의 파일에 마크업과 로직을 넣어 기술을 인위적으로 분리하지 않고
느슨하게 연결된 유닛인 ‘컴포넌트’로 관심사를 분리 (마크업과 로직 모두를 포함)

: 변수 name1 선언 후, 중괄호로 감싸 JSX 안에 사용
-> JSX의 중괄호 안에는 유효한 모든 js 표현식을 넣을 수 있음
: 컴파일이 끝나면 JSX 표현식에서 정규 js 함수가 호출되고, js 객체로 인식됨

: 인자로 사용, 변수에 할당, 함수로 반환, if/for 문 안에 사용 가능

: 표현식 삽입 시 중괄호 주변에 따옴표 입력 불가
: 따옴표는 문자열 값에, 중괄호는 표현식에 사용하고 동일한 속성에 둘다 사용 불가

-> JSX는 HTML보다는 js에 가깝기 때문에
React DOM은 HTML 속성 이름 대신, 카멜케이스 속성 명명 규칙을 사용
🔥 class => className, tabindex => tabIndex

JSX의 주입공격 방지

: JSX에 사용자 입력을 삽입하는 것은 안전
: 기본적으로 React DOM은 JSX에 삽입된 모든 값을 렌더링하기 전에 이스케이프 함
-> 앱에 명시적으로 작성되지 않은 내용은 주입되지 않음
: 모든 항목은 렌더링되기 전에 문자열로 반환
=> XSS(cross-site-scripting) 공격 방지 가능

JSX의 객체 표현

: Babel은 JSX를 React.createElement() 호출로 컴파일

React.createElement()는 버그가 없는 코드를 작성하기 위해 몇가지 검사 수행
->

객체 생성! => “React 엘리먼트”
: 화면에서 보고싶은 것을 나타내는 표현
-> React는 이 객체를 읽고 DOM 구성 -> 최신 상태로 유지

JSX 규칙

  1. 태그 꼭 닫아주기 : /> 이용해 바로 닫아주어야 함

  2. 반환되는 엘리먼트는 무조건 1개
    : 엘리먼트 두개 반환 -> 컴파일 에러 -> 하나의 div 태그로 묶어서 리턴

  1. JSX에서 js 사용하려면 중괄호 쓰기
    : 값 가져오기, map, 삼항연산자 등 문법 등 모두 {} 안에 넣어

  1. class 대신 className
    : JSX로 작성하는 태그 내에서 클래스 명을 정해줄 때

  2. 인라인으로 style 주기
    : html은 태그에 스타일 직접 넣어줌
    -> JSX에서는 css 문법 대신 json 형식으로 넣어줌

🙋🏻‍♀️ 리액트의 렌더링이란?

✅ 반복되는 컴포넌트 처리하기

map() 메소드

: map 사용하지 않고 컴포넌트 구현
: 같은 코드가 여러번 중복
: 구성요소들을 개발자가 직접 입력해줘야 함, 데이터 관리 안됨
: 구성요소가 추가되면 개발자는 화면을 추가로 개발

: 채소 이름을 배열로 만듦
: JSX 부분에서 map(), 즉 js 코드를 사용할 것이므로 {}로 먼저 감쌈
: map()은 배열의 모든 요소를 화면에 렌더링 해줌

🔥 중복된 코드가 사라지고 1개의 컴포넌트를 이용하면서
그 안에서 <div> {vegetableName} </div>가 순차적으로 보여짐

App 컴포넌트 안에 sqareStyle이 같이 있어서 코드 가독성이 좋지 않음
-> Square을 컴포넌트로 분리해보자

: App 컴포넌트에서는 map() 안에서 <Square /> 컴포넌트를 return함
: Square 컴포넌트에 props를 통해 vegetableName을 보내줌
: Square 컴포넌트에서는 props로 vegetableName을 받아
<div> {props.vegetableName} </div>로 화면에 렌더링
-> 중복코드를 없애고, 컴포넌트 분리를 통해 코드의 가독성을 높이고 각 컴포넌트의 역할을 명확히 해줌

복잡한 데이터 map()

: user 배열안에 object literal 형태의 데이터가 존재
: App 컴포넌트에서 user.map()을 통해 user의 정보를 순회하고 각각의 user 정보를 User 컴포넌트로 주입해줌
: User 컴포넌트에 props로 들어오는 user의 정보는 {id:1, age:30, name:"송중기"}
=> map() 기능을 이용해 앞으로 반복되는 컴포넌트를 간단히 화면에 표시할 수 있음

: map() 안에서도 조건식 사용 가능
: age가 25 미만인 user는 User 컴포넌트를 이용해 화면에 렌더링, else면 화면에 아무것도 렌더링하지 않음

🔥 React에서 map 사용해서 컴포넌트를 반복 렌더링할 때는 반드시 컴포넌트에 key를 넣어줘야함, 안그럼 오류
: 컴포넌트 배열을 렌더링했을 때 각각의 원소에서 변동이 있는지 알아내려고 사용하기 때문
: key가 없으면 React는 가상돔을 비교하는 과정에서 배열을 순차적으로 비교하면서 변화를 감지하려 함, 하지만 key가 있으면 이 값을 이용해서 어떤 변화가 일어났는지 더 빠르게 알 수 있음 => 성능 최적화를 위함

✅ 컴포넌트 꾸미기

CSS 이용하기

🔥 컴포넌트 파일에서 className을 넣어주고, 이 컴포넌트에서 적용할 CSS 파일을 import 해줘야함

: CSS 파일로 이동해서 원하는 스타일 코드를 넣어줌

profile
개발자가 되고싶어요
post-custom-banner

0개의 댓글