[REACT] 개념정리

😎·2022년 11월 30일
0

REACT

목록 보기
3/7

항해99 이번 주차에 팀과제로 진행한 개념정리문

노션링크 - https://teamsparta.notion.site/React-2-e21a43014e924ad487369fda21d6f205

Q

자바스크립트에서 유사배열과 배열의 차이는 무엇일까요?
유사배열의 각 요소를 수정하고 싶다면 어떤 과정을 거쳐야할까요?

A

유사 객체 배열은 배열처럼 보이지만 사실 key가 숫자이고 length 값을 가지고 있는 객체를 말한다. JS에서 querySelectorAll이나 document.body.children으로 엘리먼트를 가져오면 유사 배열 객체에 담겨서 온다.

  • 요소를 수정하는 방법
    • Array.from() 메서드는 유사 배열 객체(array-like object)나 반복 가능한 객체(iterable object)를 얕게 복사해새로운Array 객체를 만듭니다.(MDN)
    • 배열에 내포되어있는 기능들을 유사배열에서 사용하기 위해 call, apply, bind을 사용한다. (apply와 call은 함수를 호출하는 방법 중 하나로, 다른 객체에 내포되어있는 함수를 내것처럼 사용할 수 있게 해준다.)

Q

event listener는 등록되면 반드시 해제되어야 합니다.
클래스형 컴포넌트에서는 컴포넌트가 화면에서 사라질 때(unmount 될 때) event listener를 해제합니다. (componentWillUnmount에서요!)
그럼 라이프사이클 메소드를 사용할 수 없는 함수형 컴포넌트에서는 event listener를 해제할 때 어떻게 해야할까요?

A

이벤트 리스너

이벤트 리스너는 DOM객체에서 이벤트가 발생할 경우 해당 이벤트 처리 핸들러를 추가할 수 있는 오브젝트이다.

이벤트 리스너를 이용하면 특정 DOM에 위에서 말한 Javascript 이벤트가 발생할 때 특정 함수를 호출한다.

이벤트 리스너의 경우 웹 애플리케이션 메모리 누수의 원인이 될 수 있다. 더 이상 해당 이벤트 리스너가 필요 없다고 하면 반드시 추가된 이벤트 리스너는 반드시 삭제해주어야 한다.

함수형 컴포넌트에서 event listener 해제하기

그럼 라이프 사이클 메서드를 사용할 수 없는 함수형 컴포넌트에서는 어떻게 event를 실행시기고 해제해야할까?

useEffect

함수형 컴포넌트에서는 각각의 라이프사이클 메소드를 useEffect 하나로 통일시킬 수 있다. 대신 dependency를 선언하여 시점을 구분한다.

useEffect(() => {
    console.log('hi')
  }, [/* dependency 선언하는 곳 */])

빈 배열을 선언하면 최초 로드시에만 렌더링이 된다.

이벤트 실행하기

useEffect를 이용해서 최초 로드 시에 addEventListener를 사용하여 이벤트를 추가해주면 이벤트 감지가 시작된다.

useEffect(() => {
    document.addEventListener();
  }, [])
이벤트 해제하기

이벤트를 등록하고 난 뒤 성능 저하를 방지하기 위해 컴포넌트가 언마운트 될 때 꼭 이벤트 등록을 해제해주어햐 한다. 함수형 클래스에서는 useEffect의 내부 함수의 return값으로 removeEventListener를 통해 해제해주면 된다.

Q

리액트에서는 DOM 요소에 접근하기 위해 주로 ref를 씁니다.
domcument.getElementsByClassName 등을 쓰는 게 아니라 ref를 쓰는 이유는 무엇일까요?

A

일반 HTML에서 DOM요소에 이름을 달 때는 id를 사용는데 리액트 프로젝트 내부에서 DOM에 이름을 다는 방법이 ref 이다. ref를 사용하는 시기는 DOM 을 꼭 건드려야 할 때 사용하며

° 특정 input에 포커스 주기
° 스크롤 박스 조작하기
° Canvas 요소에 그림 그리기등

위와 같은 경우에는 어쩔 수 없이 DOM에 직접적으로 접근해야한다.리액트 공식 문서에 보면
선언적으로 해결될 수 있는 문제에서는 ref 사용을 지양해야한다.
ref의 사용을 최대한 줄여야 한다고 명시되어있다.

대충 ref에 대한 설명을 하였고 사용하는 이유는?
id는 유일해야 하지만 컴포넌트 재사용을 한다면 중복될 가능성이 있다.
ref는 전역적으로 작동하지 않고 컴포넌트 내부에서만 작동한다.

하지만 리액트에서도 id를 사용할 수는 있다👍

Q

SPA 방식과 MPA 방식은 무엇인가요?

A

SPA(Single Page Application)는 한 개(single)의 Page로 구성된 application 이고,

MPA(Multi Page application)는 여러 개(multi)의 Page로 구성된 application 이다.

MPA는 새로운 페이지를 요청할 때마다 정적 리소스가 다운로드 되고,그에 맞춰 전체 페이지를 다시 렌더링한다.인터넷 주소창에 주소를 입력하거나, 링크를 클릭하는 등 사용자가 어떤 요청을 하면,그에 맞는 html, 이미지 등의 파일들이 전부 다운로드 되고 다시 렌더링 된다.

반면 SPA는 웹 애플리케이션에 필요한 모든 정적 리소스를 최초 한번에 다운로드한다.그 이후 새로운 페이지 요청이 있을 경우,페이지 갱신에 필요한 데이터만 전달받아 페이지를 갱신한다.어떤 링크를 클릭한다고 해서 그에 관련된 모든 파일을 다운받는게 아니라,필요한 정보만 받아서 그 정보를 기준으로 업데이트 될 뿐이다.

Q

element(엘리먼트)란?

A

리액트에서 가장 작은 단위이며, 화면에 표시할 내용을 기술하는 것을 말함
쉽게 생각하면, 엘리먼트는 컴포넌트의 구성 요소이고,
반대로 컴포넌트를 엘리먼트로 구성되어 있다고 생각 할 수 있다

ex) const element = <span>hello</span>;

어떻게 사용할까 ?

React 엘리먼트를 루트 DOM 노드에 렌더링하려면 ReactDOM.render()로 전달하면 된다.
ex)

const element = <h1>hello, GodDaeHee!~</h1>;
ReactDOM.render(element, document.getElementById('root'));

위와 같은 원리로 엘리먼트를 생성하고 렌더링 하는데,
JSX를 사용한다면 이 작업을 바벨이 편하게 알아서 해석 해주게 된다.

Q

props란?

A

프로퍼티, props(properties의 줄임말) 이며,
상위 컴포넌트가 하위 컴포넌트로 값을 전달할때 사용 한다
(단방향 흐름 데이터 흐름을 가지며 하위 컴포넌트에서 읽기전용이다)

어떻게 사용할까?

프로퍼티에 문자열을 전달할 때는 큰따옴표(" ")를,
문자열 외의 값을 전달할 때는 중괄호({ })를 사용 한다.
ex )

props={} , props=""

참고할 만한 사용법
프로퍼티의 자료형을 미리 선언할 수 있다
ex)

Main.propTypes = { name: PropTypes.string }

컴포넌트에 props 기본값을 설정하고 싶은 경우 defaultProps를 설정하면 된다.
ex)

Main.defaultProps = { name: '디폴트' }

디폴트 설정을 하지 않는 경우 해당 프로퍼티를 필수 프로퍼티로 선언 할 수도 있다.
ex)

Main.propTypes = {name: PropTypes.string.isRequired, }

Q

JSX란?

A

  • HTML도아닌 JSX(JavaScript XML)라는 JavaScript에 XML을 추가하여 확장한 문법이다
  • JSX는 React “엘리먼트(element)” 를 생성한다. React 엘리먼트는 브라우저 DOM 엘리먼트와 달리 일반 객체이다
  • React는 JSX 사용이 필수가 아니지만, JS 코드 안에서 UI관련 작업을 할 수 있기 때문에 시각적으로 더 도움이 된다
  • 또한 JSX를 사용하면 React가 더욱 도움이 되는 에러 및 경고 메시지를 표시할 수 있게 해준다

JSX 사용하기

  • 어떤 프레임워크를 사용해 웹앱을 만들든 가장 중요한 것은 최종결과가 HTML, CSS, JS의 조합이어야 한다는 것이다. (그렇지 않으면 브라우저가 이해하지 못하기 때문이다)
  • 리액트로 개발을 할 때 HTML, CSS, JS 코드를 작성하기도 하지만 상당부분을 JSX로 코드를 작성해야한다. 하지만 JSX는 공식적인 JS문법이 아니기 때문에 브라우저는 JSX를 이해하지 못한다. 그래서 리액트로 개발을 할 때는 JSX를 브라우저가 이해할 수 있는 평범한 자바스크립트로 변환시킬 방법이 필요하다.

JSX변환방법

  1. Node.js와 그 외 빌드 툴 등으로 구성된 개발환경을 구축하여 리액트로 개발하는 것
  • 빌드 툴을 이용해 JSX로 작성된 코드들이 JS로 변환되며, 다른 일반적인 JS 파일처럼 참조할 수 있도록 변환된 파일이 디스크에 저장된다.
  • 장점 : 오늘날 현대적인 웹개발에서 대표적인 방식, JSX에서 JS로 트랜스 파일됨, 여러 모듈과 빌드 툴 그리고 그 외 복잡한 웹앱의 관리에 필요한 많은 기능 이용 가능
  • 단점 : 처음에는 약간 복잡하고 시간이 걸림
  1. 런타임 시 브라우저가 JSX를 JS로 자동 변환 하게 해주는 방법
  • CDN을 이용하는 방식으로, 일반 JS처럼 JSX를 직접 지정하면 브라우저가 알아서 처리한다. 브라우저가 실행 될 때 CDN으로 연결한 스크립트 파일 하나만 참조하고, 그 스크립트 파일은 페이지가 로딩 될 때 JSX를 JS로 변환한다.
  • 장점 : 개발 환경 세팅 시간을 절약하고 코드 작성에 더 많이 집중 가능
  • 단점 : 브라우저가 매번 JSX를 JS로 변환해야 하는데, 이로 인해 소요되는 시간이 길어지면 브라우저 성능 저하를 야기 할 수 있다. 성능 이슈가 있으므로 실제 웹 개발에서는 사용하지 않음.

JSX 장점

  1. 보기 쉽고 익숙하다
  • JSX는 HTML 코드와 비슷하기 때문에 일반 자바스크립만 사용한 코드보다 더 익숙하며 가독성이 좋다.
  1. 높은 활용도
  • JSX에는 div, span 같은 HTML 태그를 사용할 수 있으며, 개발자가 만든 컴포넌트도 JSX 안에서 작성할 수 있다.

JSX 특징

  1. 대소문자를 구별한다
  • JSX에서 HTML엘리먼트를 작성할 때는 반드시 소문자를 사용해야 하지만, 컴포넌트를 작성할 때는 컴포넌트 클래스 이름과 동일하게 PascalCase로 작성되어야 한다.
  1. 주입공격을 방지한다
  • 기본적으로 React DOM은 JSX에 삽입된 모든 값을 렌더링하기 전에 이스케이프 처리하므로, 애플리케이션에서 명시적으로 작성되지 않은 내용은 주입되지 않는다. 모든 항목은 렌더링 되기 전에 문자열로 변환된다. 이런 특성으로 인해 XSS (cross-site-scripting) 공격을 방지할 수 있다.
  1. 객체를 표현한다

JSX문법

  1. 반드시 태그는 닫혀야한다
  • <div>, <p>, <span>, <a> 같이 짝이 있는 태그의 경우 반드시 닫는 태그가 존재해야 한다. 그렇지 않을 경우 에러가 발생한다.
  • <img/>, <input/>, <br/> 같은 단독 태그(self-closing tag)의 경우에는 반드시 태그를 닫아줘야 한다. 그렇지 않을 경우 에러가 발생한다.
  1. 렌더링 될 루트 엘리먼트는 하나만 존재해야한다
  • 렌더링 될 리액트 엘리먼트에서 루트 엘리먼트가 두 개 이상일 경우 에러가 발생한다. 때문에 두 개 이상의 루트 엘리먼트가 존재할 경우 반드시 하나의 엘리먼트로 감싸져야 한다.

(JSX는 자식 엘리먼트를 가질 수 있다.)

  • Virtual DOM에서 컴포넌트 변화를 감지해 낼 때 효율적으로 비교할 수 있도록 컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙 때문에, 리액트에서는 반드시 컴포넌트에 여러 요소가 있다면 반드시 부모 요소로 감싸야 한다.

Point

state는 일반 자바스크립트 객체고, 함수 내부에 선언된 변수처럼 컴포넌트 내부에서 사용됩니다.

  • state는 일반 자바스크립트 객체고, 함수 내부에 선언된 변수처럼 컴포넌트 내부에서 사용된다
  • 일반적으로 컴포넌트 내부에서 변경이 가능한 데이터를 관리할 때 사용한다.
  • state는 렌더링 되는 결과물에 영향을 미치는 요소 중 하나고, 기본적으로 state에 변경이 생기면 컴포넌트는 리렌더링 된다.
  • state는 사용자와의 interaction이나 네트워크 변경 이벤트의 결과로 변경된다.
  • state 값을 변경하기 위해선 state 자체의 값을 변경하는 것이 아니라 setState() 함수를 사용해서 변경해야한다.

Q

컴포넌트(Component)란?

A

- 리액트로 만들어진 앱을 이루는 최소한의 단위

  • 기존의 웹 프레임워크는 MVC방식으로 분리하여 관리하여 각 요소의 의존성이 높아 재활용이 어렵다는 단점이 있었다. 반면 컴포넌트는 MVC의 뷰를 독립적으로 구성하여 재사용을 할 수 있고 이를 통해 새로운 컴포넌트를 쉽게 만들 수 있다. - 컴포넌트는 데이터(props)를 입력받아 View(state) 상태에 따라 DOM Node를 출력하는 함수. - 컴포넌트 이름은 항상 대문자로 시작하도록 한다.    (리액트는 소문자로 시작하는 컴포넌트를 DOM 태그로 취급하기 때문이다.

  • UI를 재사용 가능한 개별적인 여러 조각으로 나누고, 각 조각을 개별적으로 나누어 코딩한다.

  • “props”라고 하는 임의의 입력을 받은 후, 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환한다.

  • props와 state 등의 특징들은 따로 정리 하도록 한다.

1) 함수형 컴포넌트 (Stateless Functional Component) - 가장 간단하게 컴포넌트를 정의하는 방법은 자바스크립트 함수를 작성하는 것이다. - 하기 예시의 export는 구문은   작성한 MyComponent 파일을 다른 파일에서 import 할때 MyComponent로 불러올 수 있도록 정의해 주는 부분이다.

  • 여기서 import시 js, jsx 등 파일 확장자를 생략해도 자동으로 찾을 수 있다. 이는 "웹팩 코드 검색 확장자(webpack module resolution)" 기능 때문이다. 확장자가 파일 이름에 없는 경우 웹팩의 확장자 옵션(extentions)에 정의된 확장자 목록을 통해 확장자 이름을 포함한 파일이 있는지 확인하여 자동으로 임포트 한다.
    2) 클래스형 컴포넌트 ( Class Component )

- 컴포넌트 구성 요소, 리액트 생명주기를 모두 포함하고 있다. (리액트 생명주기는 따로 조금더 자세히 알아보도록 한다.)

  • 프로퍼티, state, 생명주기 함수가 필요한 구조의 컴포넌트를 만들 때 사용한다.

Q

Hook이란?

A

  • 기존 리액트는 컴포넌트 재사용이 가능한 로직이 추가되지 않았음. state를 사용하기 위해선 class를 사용해야 했는데, Hook은 함수형 컴포넌트에서도 state를 사용하기 위해 새로 만들어진 개념.
  • 함수형 컴포넌트에서 state를 관리할 경우, 기존 클래스형 컴포넌트보다 코드가 더 간결해지는 효과를 볼 수 있다. 함수형 컴포넌트를 사용할 경우, 기능들을 함수 단위로 분리할 수 있다는 이점이 있기 때문.
  • 리액트는 기본적으로 두 가지의 Hook을 제공한다.
    • useState
      • useState() 함수는 배열을 리턴하도록 설계되어 있다.
      • useState 사용 시, 매개변수 2개를 사용하는데, 첫번째는 state의 값을 상징하고, 두번째는 state를 변경하는 함수다.
        • 기본적으로 const [state, setState] = useState() 형태로 사용한다.
    • useEffect
      • 컴포넌트가 처음 나타낼 때, 사라질 때, 그리고 업데이트 될 때 (특정 props가 변경될때) 등 컴포넌트가 렌더링될 때 특정 작업을 실행하는 Hook이다.
      • useEffect(effect, [, deps]); 형태로 사용되는데, 첫번째 인자(effect)는 함수, 두번째 인자는 배열(deps)이 들어간다.
        • effect는 렌더링 이후 실행될 함수를 의미한다.
        • deps는 특정한 값이 변경될 때, effect함수를 실행 하고 싶을 경우 배열 안에 그 값을 넣어준다.
        • 빈 배열을 입력할 경우 컴포넌트가 처음 실행될 때만 실행 된다.
  • Hook을 사용하기 위한 규칙:
    • Hook은 최상위에서만 호출되어야하고, 호출 순서는 항상 같아야 한다.
      • 리액트는 훅이 사용된 순서로 상태값을 구분한다.
        • 예를 들어 반복문 안에서 Hook을 호출했을 때, 값이 false라면 해당 부분을 건너뛰게 되는데, 이때 Hook의 실행 순서에 문제가 생겨서 오류가 생긴다..
      • 조건문이나 반복문을 사용하고 싶다면 useEffect 내부에서 hook을 사용해야 한다.
    • Hook은 리액트 내부에서만 사용 가능.
      • 일반 자바스크립트 함수에서 hook을 사용할 수 없다.
profile
개발 블로그

0개의 댓글