상세 컨텐츠

본문 제목

[React] 리액트에서 Fragment, Portal, ref 의 역할 (feat. Udemy - React Complete Guide 강의)

Studying (Review)/React

by 잼(JAM) 2022. 9. 26. 23:32

본문

반응형

1. Fragments에 대해

1-1. JSX에서 root 태그는 하나만 존재할 수 있다

JSX는 HTML과 JavaScript를 하나의 컴포넌트로 만들어
렌더링 시켜주는 문법이라고 할 수 있다.(HTML in JS 라고나 할까..?)

 

JSX 소개 – React

A JavaScript library for building user interfaces

ko.reactjs.org

결국 JSX는 컴파일 되어 JavaScript로 표현이 되는데,
이 때 React.createElement() 호출을 통해서 컴파일이 이루어지게 된다.(참조)
JSX 문법을 사용해서 렌더링할 컴포넌트를 return 안에서 호출하고 있기 때문에,
return이라는 키워드의 측면에서 생각해본다면
JSX는 단 하나의 root를 가질 수 밖에 없다는 것이 납득이 될 것 같다.

 

JSX 소개 – React

A JavaScript library for building user interfaces

ko.reactjs.org

이러한 이유에서 JSX를 작성할 때, Wrapper로 div 등을 사용하게 되는데
아무리 wrapper라고 해도 div를 너무 많이 사용하는 것이 문제가 생길 수 있다.

(JSX의 제약사항으로 인해 작성한 div라도 DOM에 전부 렌더링 되기 때문에)

 

너무 귀찮겠죠..?

다른 방법으로는 return 안에서 배열(Array)을 사용하는 방법이 있다.
하지만 모든 컴포넌트를 이러한 방식으로 작성하는 것은
손이 너무 많이 가고(key값을 일일이 넣어줘야 하기 때문에)
그만큼 유지보수성에도 어려움이 생기기 때문에 이렇게 작성하지 않는다.


개발자의 영원한 숙제: 에러핸들링, 성능개선

1-2. 불필요한 태그 중첩으로 일어나는 문제

위에서 말했던 중첩되는 태그들로 일어나는 문제는
크게 두 가지 정도가 있을 수 있다.
(여러가지 문제가 있을 수 있지만, 가장 대표적인 것들)

 

하나는 스타일링을 적용할 때 문제가 될 수 있다는 것이다.
중간중간에 삽입되어 있는 태그들 때문에
의도치 않게 스타일링 적용에 방해가 될 수 있다.

 

또 하나는 결과적으로는 제작한 애플리케이션의 속도가 느려질 수 있다는 것이다.
(불필요한 렌더링 과정이 추가되는 것이기 때문에)


1-3. Fragments가 해결해주는 것

DOM을 생성하지 않는 Wrapper 컴포넌트를 만들게 되면 어떨까?

JSX 문법을 그대로 사용하는 한 편, 실제 DOM에는 렌더링 되지 않는다
이것은 불필요한 렌더링을 요구하지 않기 때문에,
스타일링에도 간섭하지 않고, 성능상에서 큰 이점이 될 수 있다.

기본적으로 왼쪽의 문법으로 사용한다. 오른쪽은 단축문법이다 (이미지 클릭시 강의로 이동)

children을 반환하는 Wrapper 컴포넌트를 만들어 사용할 수도 있겠지만,
React에서는 이것을 Fragment 라는 기능으로 제공하고 있다.(참조)

 

Fragments – React

A JavaScript library for building user interfaces

ko.reactjs.org


2. Portal에 대해

우리가 생각하는 포탈..

2-1. Portal을 사용하는 이유

모달은 보통 최상위에서 렌더링 되어야 한다 (이미지 클릭시 강의로 이동)

modal과 같은 기능구현을 위해 컴포넌트를 작성했을 때,
동작은 가능하지만 원하는대로의 렌더링이 일어나지 않을 수 있다.
(CSS의 상속이 일어나서 원하는대로 보이지 않을 가능성이 존재)

 

또한 구조상 여러 컴포넌트가 중첩되어 있는 경우에도
원하는대로 동작이 일어나기가 어려울 수 있다.


2-2. Portal이 해결해주는 것

(이미지 클릭시 강의로 이동)

이 modal을 가장 바깥인 root 와 같은 레벨에서 렌더링 되도록 하면 어떨까?
root 안에서의 상속이 아니라, 바깥에서 렌더링 되기 때문에
CSS의 상속을 피하고 원하는대로 동작할 수 있게 만들 수 있다.

리액트에서는 이것을 Portal이라는 기능으로 제공하고 있다(참조)

 

Portals – React

A JavaScript library for building user interfaces

ko.reactjs.org


3. ref(reference) 에 대해

reference 라는 단어의 뜻처럼 '참조' 의 역할을 한다

3-1. ref 를 사용하는 이유?

ref 의 가장 기본적인 기능은
다른 DOM 요소에 접근하여 그것으로 작업이 가능하도록 하는것이다

state를 활용하는 code의 line은 길어지기가 쉽다

보통 input 과 같은 요소에서 많이 활용하게 되는데,
state를 대체하여 활용이 가능하다.
ref 가 기본적으로 가지고 있는 current 속성을 통해
value에 접근하여 현재 입력된 값을 가져올 수 있다

state가 없어서 code line이 비교적 간결해졌다.

다만, ref 의 경우 DOM을 직접적으로 조작이 가능하기 때문에
값을 가져오는 경우에만 활용하도록 권장되는 것 같다.
(재설정 로직 같은 곳에 활용은 가능하지만, 일반적이지 않다고 한다.)


3-2. 제어 컴포넌트와 비제어 컴포넌트

상황에 따라 제어가 필요하거나 필요하지 않을 수 있다

ref 를 사용해 DOM 에 접근하여 값을 가져온다면,
비제어 컴포넌트라고 할 수 있다.


useRef 라는 리액트 훅을 사용하지만,
React 가 다시 데이터를 보내는 등의 내부 state 에 관여하지 않기 때문에
비제어(리액트를 통해 제어되지 않는) 컴포넌트라고 부르게 되는 것이다.
(비제어 컴포넌트에 대한 내용은 여기를 참조하면 좋을 것 같다.)

 

비제어 컴포넌트 – React

A JavaScript library for building user interfaces

ko.reactjs.org

그에 반해, state 를 사용하여 값을 가져오거나 다시 쓰고
이것을 활용하여 동작하도록 로직을 작성한다면
제어 컴포넌트라고 할 수 있다.

 

React 가 change 이벤트 등을 통하여 value에 접근하고
해당 데이터를 수정하여 다시 쓰거나 하는 등
내부 state 에도 관여를 하기 때문에 제어 컴포넌트라고 부르게 되는 것이다

 

비제어 컴포넌트와 제어 컴포넌트의 기능비교 (이미지 클릭시 본 글로 이동)

제어컴포넌트와 비제어 컴포넌트는 상황에 맞게 선택하여 사용할 수 있다.(참조)

 

Controlled and uncontrolled form inputs in React don't have to be complicated - Gosha Arinich

There are many articles saying you should use setState, and the docs claim refs are bad. So contradictory. How are you supposed to make forms?

goshacmd.com

데이터의 변화 감지가 실시간으로 요구되지 않는다면,
비제어 컴포넌트를 사용할 수 있을 것이고

 

데이터의 변화 감지가 실시간으로 요구되거나,
해당 데이터를 양식에 맞추어 작성하도록 요구해야 하거나,
여러가지 데이터, 동적인 입력등의 복잡한 로직이 요구된다면
제어 컴포넌트를 사용하는 것이 적합할 것이다.

 

따라서 필요에 따라 적절하게 작성하여 사용하는 것이 중요할 것 같다!

반응형

관련글 더보기

댓글 영역