CS 간단 정리 - 프론트엔드

리액트에서 컴포넌트란 무엇인가요?

리액트에서 컴포넌트는 UI를 구성하는 독립적이고 재사용 가능한 코드 조각이라고 설명드릴 수 있습니다. 컴포넌트는 특정 기능이나 UI 요소를 캡슐화합니다. 잘 만들어진 컴포넌트는 주로 단일 책임 원칙을 따릅니다.
리액트 내에서 컴포넌트는 크게 클래스형함수형으로 나눌 수 있는데, 최근에는 Hooks의 도입으로 함수형 컴포넌트가 주로 사용되고 있습니다. 함수형 컴포넌트는 더 간결하고 이해하기 쉬운 코드를 작성할 수 있게 해줍니다.
컴포넌트의 주요 장점은 재사용성유지보수성입니다. 예를 들어, 버튼 컴포넌트를 한 번 만들면 여러 페이지에서 다양한 스타일과 기능으로 재사용할 수 있습니다. 또한 컴포넌트는 props를 통해 부모로부터 데이터를 전달받을 수 있어, 동적인 UI를 손쉽게 구현할 수 있습니다.
 
  • 컴포넌트 설계 시 중요하게 고려해야 하는 사항에는 어떤 것들이 있나요? 🤔
React 컴포넌트 설계 시에는 다음과 같은 사항들을 고려해야 합니다.
첫째, 하나의 컴포넌트가 너무 많은 책임을 갖지 않도록 해야 합니다. 컴포넌트의 역할이 명확하도록 설계해야 합니다. 물론, 이를 고려하지 않아도 정상 작동은 하겠지만, 추후의 유지보수성을 고려해야 하는 상황이라면 하나의 컴포넌트가 너무 많은 책임을 가지지 않도록 하는 것이 중요합니다. 대표적인 예시로, 비즈니스 로직과 UI 로직을 철저히 분리하는 것을 들 수 있습니다.
둘째, 재사용성을 고려해야 합니다. 만약 특정 컴포넌트가 여러 상황에서 재사용될 가능성이 높다면 유연하게 설계해야 추후 재사용이 용이합니다. props를 통해 필요한 데이터와 동작을 주입받아 다양한 상황에서 쉽게 재사용될 수 있도록 하는 것이 좋습니다. 이를 '컴포넌트가 춤을 춘다'고 비유적으로 표현하기도 합니다.
셋째, 성능 최적화를 고려해야 합니다. 불필요한 리렌더링을 방지하기 위해 메모이제이션을 적절히 활용하고, 컴포넌트의 크기를 적절히 유지해야 하는 것이 좋습니다.
사실, 이밖에도 고려해야 할 상황이 정말 많으며, 앞서 말씀드린 사항들이 모든 상황에 똑같이 적용되는 것도 아닙니다. 가장 중요한 것은, 각각의 상황에 맞는 컴포넌트를 만드는 것이라고 생각합니다. 유지보수성, 성능, 재사용성 등이 어떠한 상황에서는 중요할 수도, 어떠한 상황에서는 중요하지 않을 수도 있습니다. 이를 적절하게 판단하여 당장의 상황에 부합하는 최적의 컴포넌트를 만들어 내기 위해 고민하는 태도가 중요합니다.
매일메일 - 리액트에서 컴포넌트란 무엇인가요?
리액트에서 **컴포넌트는 UI를 구성하는 독립적이고 재사용 가능한 코드 조각**이라고 설명드릴 수 있습니다. 컴포넌트는 특정 기능이나 UI 요소를 캡슐화합니다. 잘 만들어진 컴포넌트는 주로 단일 책임 원칙을 따릅니다. 리액트 내에서 컴포넌트는 크게 **클래스형**과 **함수형**으로 나눌 수 있는데, 최근에는 Hooks의 도입으로 함수형 컴포넌트가 주로 사용되고 있습니다. 함수형 컴포넌트는 더 간결하고 이해하기 쉬운 코드를 작성할 수 있게 해줍니다. 컴포넌트의 주요 장점은 **재사용성**과 **유지보수성**입니다. 예를 들어, 버튼 컴포넌트를 한 번 만들면 여러 페이지에서 다양한 스타일과 기능으로 재사용할 수 있습니다. 또한 컴포넌트는 props를 통해 부모로부터 데이터를 전달받을 수 있어, 동적인 UI를 손쉽게 구현할 수 있습니다. ## 컴포넌트 설계 시 중요하게 고려해야 하는 사항에는 어떤 것들이 있나요? 🤔 React 컴포넌트 설계 시에는 다음과 같은 사항들을 고려해야 합니다. 첫째, **하나의 컴포넌트가 너무 많은 책임을 갖지 않도록 해야 합니다.** 컴포넌트의 역할이 명확하도록 설계해야 합니다. 물론, 이를 고려하지 않아도 정상 작동은 하겠지만, 추후의 유지보수성을 고려해야 하는 상황이라면 하나의 컴포넌트가 너무 많은 책임을 가지지 않도록 하는 것이 중요합니다. 대표적인 예시로, 비즈니스 로직과 UI 로직을 철저히 분리하는 것을 들 수 있습니다. 둘째, **재사용성을 고려**해야 합니다. 만약 특정 컴포넌트가 여러 상황에서 재사용될 가능성이 높다면 유연하게 설계해야 추후 재사용이 용이합니다. props를 통해 필요한 데이터와 동작을 주입받아 다양한 상황에서 쉽게 재사용될 수 있도록 하는 것이 좋습니다. 이를 '컴포넌트가 춤을 춘다'고 비유적으로 표현하기도 합니다. 셋째, **성능 최적화**를 고려해야 합니다. 불필요한 리렌더링을 방지하기 위해 메모이제이션을 적절히 활용하고, 컴포넌트의 크기를 적절히 유지해야 하는 것이 좋습니다. 사실, 이밖에도 고려해야 할 상황이 정말 많으며, 앞서 말씀드린 사항들이 모든 상황에 똑같이 적용되는 것도 아닙니다. 가장 중요한 것은, **각각의 상황에 맞는 컴포넌트를 만드는 것**이라고 생각합니다. 유지보수성, 성능, 재사용성 등이 어떠한 상황에서는 중요할 수도, 어떠한 상황에서는 중요하지 않을 수도 있습니다. 이를 적절하게 판단하여 **당장의 상황에 부합하는 최적의 컴포넌트**를 만들어 내기 위해 고민하는 태도가 중요합니다. ## 📚 추가 학습 자료를 공유합니다. - [토스ㅣSLASH 22 - Effective Component 지속 가능한 성장과 컴포넌트](https://www.youtube.com/watch?v=fR8tsJ2r7Eg) - [[10분 테코톡] 호프의 프론트엔드에서 컴포넌트](https://www.youtube.com/watch?v=aAs36UeLnTg)
 

CORS란 무엇인가요?

CORS(Cross Origin Resource Sharing)는 출처가 다른 곳의 리소스를 요청할 때 접근 권한을 부여하는 메커니즘입니다. 리소스를 주고받는 두 곳의 출처가 다르면 출처가 교차한다고 합니다. 이때 출처는 URL뿐만 아니라 프로토콜과 포트까지 포함됩니다. 만약 클라이언트의 출처가 허용되지 않았다면 CORS 에러가 발생할 수 있습니다.
 
  • CORS는 왜 필요한가요?
과거에는 크로스 사이트 요청 위조(CSRF, Cross-Site Request Forgery) 문제가 있었습니다. 피해자의 브라우저에서 다른 애플리케이션으로 가짜 클라이언트 요청을 전송하는 공격입니다.
CSRF를 예방하기 위해 브라우저는 동일 출처 정책(SOP, same-origin policy)을 구현했습니다. SOP가 구현된 브라우저는 클라이언트와 동일한 출처의 리소스로만 요청을 보낼 수 있습니다.
하지만, SOP는 한계가 있습니다. 현대의 웹 애플리케이션은 다른 출처의 리소스를 사용하는 경우가 많기 때문입니다. 따라서, SOP를 확장한 CORS가 필요합니다.
 
  • CORS는 어떻게 작동할까요? 🤔
브라우저가 요청 메시지에 Origin 헤더와 응답 메시지의 Access-Control-Allow-Origin 헤더를 비교해서 CORS를 위반하는지 확인합니다. 이때, Origin에는 현재 요청하는 클라이언트의 출처(프로토콜, 도메인, 포트)가, Access-Control-Allow-Origin은 리소스 요청을 허용하는 출처가 작성됩니다.
이렇게 단순하게 요청하는 것을 Simple Request라고 합니다. Simple Request은 요청 메서드(GET, POST, HEAD), 수동으로 설정한 요청 헤더(Accept, Accept-Language, Content-Language, Content-Type, Range), Content-Type 헤더(application/x-www-form-urlencoded, multipart/form-data, text/plain)인 경우에만 해당합니다.
브라우저가 사전 요청을 보내는 경우도 있습니다. 이때 사전 요청을 Preflight Request라고 합니다. 브라우저가 본 요청을 보내기 이전, Preflight Request를 OPTIONS 메서드로 요청을 보내어 실제 요청이 안전한지 확인합니다.
Preflight Request는 추가로 Access-Control-Request-Method로 실 요청 메서드와, Access-Control-Request-Headers 헤더에 실 요청의 추가 헤더 목록을 담아서 보내야 합니다.
이에 대한 응답은 대응되는 Access-Control-Allow-Methods와 Access-Control-Headers를 보내야 하고, Preflight Request로 인한 추가 요청을 줄이기 위해 캐시 기간을 Access-Control-Max-Age에 담아서 보내야 합니다.
또한 인증된 요청을 사용하는 방식도 있는데요. 이를 Credential Request라고 합니다. 쿠키나 토큰과 같은 인증 정보를 포함한 요청은 더욱 안전하게 처리되어야 합니다. 이때 Credential Request를 수행합니다.
Credential Request를 요청하는 경우에는 서버에서는 Access-Control-Allow-Credentials를 true로 설정해야 하며 Access-Control-Allow-Origin에 와일드카드를 사용하지 못합니다.
매일메일 - CORS란 무엇인가요?
CORS(Cross Origin Resource Sharing)는 출처가 다른 곳의 리소스를 요청할 때 접근 권한을 부여하는 메커니즘입니다. 리소스를 주고받는 두 곳의 출처가 다르면 출처가 교차한다고 합니다. 이때 출처는 URL뿐만 아니라 프로토콜과 포트까지 포함됩니다. 만약 클라이언트의 출처가 허용되지 않았다면 CORS 에러가 발생할 수 있습니다. ## CORS는 왜 필요한가요? 과거에는 크로스 사이트 요청 위조(CSRF, Cross-Site Request Forgery) 문제가 있었습니다. 피해자의 브라우저에서 다른 애플리케이션으로 가짜 클라이언트 요청을 전송하는 공격입니다. CSRF를 예방하기 위해 브라우저는 동일 출처 정책(SOP, same-origin policy)을 구현했습니다. SOP가 구현된 브라우저는 클라이언트와 동일한 출처의 리소스로만 요청을 보낼 수 있습니다. 하지만, SOP는 한계가 있습니다. 현대의 웹 애플리케이션은 다른 출처의 리소스를 사용하는 경우가 많기 때문입니다. 따라서, SOP를 확장한 CORS가 필요합니다. ## CORS는 어떻게 작동할까요? 🤔 브라우저가 요청 메시지에 Origin 헤더와 응답 메시지의 Access-Control-Allow-Origin 헤더를 비교해서 CORS를 위반하는지 확인합니다. 이때, Origin에는 현재 요청하는 클라이언트의 출처(프로토콜, 도메인, 포트)가, Access-Control-Allow-Origin은 리소스 요청을 허용하는 출처가 작성됩니다. 이렇게 단순하게 요청하는 것을 **Simple Request**라고 합니다. Simple Request은 요청 메서드(GET, POST, HEAD), 수동으로 설정한 요청 헤더(Accept, Accept-Language, Content-Language, Content-Type, Range), Content-Type 헤더(application/x-www-form-urlencoded, multipart/form-data, text/plain)인 경우에만 해당합니다. 브라우저가 사전 요청을 보내는 경우도 있습니다. 이때 사전 요청을 **Preflight Request**라고 합니다. 브라우저가 본 요청을 보내기 이전, Preflight Request를 OPTIONS 메서드로 요청을 보내어 실제 요청이 안전한지 확인합니다. Preflight Request는 추가로 Access-Control-Request-Method로 실 요청 메서드와, Access-Control-Request-Headers 헤더에 실 요청의 추가 헤더 목록을 담아서 보내야 합니다. 이에 대한 응답은 대응되는 Access-Control-Allow-Methods와 Access-Control-Headers를 보내야 하고, Preflight Request로 인한 추가 요청을 줄이기 위해 캐시 기간을 Access-Control-Max-Age에 담아서 보내야 합니다. 또한 인증된 요청을 사용하는 방식도 있는데요. 이를 **Credential Request**라고 합니다. 쿠키나 토큰과 같은 인증 정보를 포함한 요청은 더욱 안전하게 처리되어야 합니다. 이때 Credential Request를 수행합니다. Credential Request를 요청하는 경우에는 서버에서는 Access-Control-Allow-Credentials를 true로 설정해야 하며 Access-Control-Allow-Origin에 와일드카드를 사용하지 못합니다. ## 추가 학습 자료를 공유합니다. - [토스페이먼츠 - CORS 대응하기](https://docs.tosspayments.com/blog/payment-window-cors-error#%EA%B2%B0%EC%A0%9C%EC%B0%BD%EC%97%90%EC%84%9C-cors-%EB%8C%80%EC%9D%91%ED%95%98%EA%B8%B0) - [MDN - 교차 출처 리소스 공유 (CORS)](https://developer.mozilla.org/ko/docs/Web/HTTP/CORS) - [테코블 - CORS란?](https://tecoble.techcourse.co.kr/post/2020-07-18-cors/)

서버 컴포넌트에 대해서 설명해주세요.

서버 컴포넌트는 리액트 18 버전에서 도입된 새로운 기능입니다. 기본적으로 클라이언트에서 실행되는 기존의 리액트 컴포넌트와 다르게 서버에서만 렌더링되는 컴포넌트를 말합니다. 서버에서만 실행되기 때문에 브라우저 쪽 번들 크기를 줄이고, 초기 로딩 속도를 개선하는 데 큰 장점이 있습니다.
예를 들어, 서버 컴포넌트는 데이터베이스나 API에서 데이터를 가져오는 작업을 서버에서 처리하고, 그 결과를 클라이언트로 보낼 수 있어서 클라이언트와 서버 간의 데이터 통신을 줄일 수 있습니다. 그래서 클라이언트는 필요한 HTML과 JSON만 전달받아 렌더링하면 됩니다.
또한, 서버 컴포넌트는 보안 측면에서도 강점이 있습니다. 데이터베이스 연결 정보나 API 키 같은 민감한 정보를 클라이언트로 보내지 않아도 되는 구조라 안전하게 데이터를 다룰 수 있습니다.
리액트에서는 서버 컴포넌트를 클라이언트 컴포넌트와 함께 사용할 수 있도록 설계했습니다. 클라이언트 컴포넌트는 인터랙션이 필요한 UI를 담당하고, 서버 컴포넌트는 데이터 중심의 UI를 담당하는 식으로 역할을 분리할 수 있습니다.
결론적으로, 서버 컴포넌트는 성능 최적화와 보안 개선, 그리고 개발자 경험 측면에서 많은 이점을 가져다줄 수 있는 기능이라고 말씀드릴 수 있습니다.
 
  • 서버 컴포넌트의 단점은 없을까요? 🤔
첫 번째로는 서버 의존성 증가입니다. 서버 컴포넌트는 이름 그대로 서버에서 실행되기 때문에, 서버가 반드시 필요합니다. 따라서 서버가 다운되거나 응답 시간이 느려지면 클라이언트에서도 영향을 받게 됩니다. 특히, 정적 사이트나 서버리스 환경에서 작업하려는 경우에는 사용할 수 없거나 제약이 있을 수 있습니다.
두번째로는 사용자 경험인터랙션 문제입니다. 서버 컴포넌트는 클라이언트 컴포넌트와 결합해서 사용해야 하는데, 이 과정에서 복잡한 사용자 인터랙션(예: 실시간 업데이트, 드래그 앤 드롭 등)을 처리하기 어렵습니다. 서버 컴포넌트는 주로 정적인 데이터나 렌더링에 적합하기 때문에, 클라이언트 쪽의 인터렉션이 필요한 경우에는 한계가 있을 수 있습니다.
매일메일 - 서버 컴포넌트에 대해서 설명해주세요.
`서버 컴포넌트`는 리액트 18 버전에서 도입된 새로운 기능입니다. 기본적으로 클라이언트에서 실행되는 기존의 리액트 컴포넌트와 다르게 **서버에서만 렌더링되는 컴포넌트**를 말합니다. 서버에서만 실행되기 때문에 브라우저 쪽 번들 크기를 줄이고, 초기 로딩 속도를 개선하는 데 큰 장점이 있습니다. 예를 들어, 서버 컴포넌트는 데이터베이스나 API에서 데이터를 가져오는 작업을 서버에서 처리하고, 그 결과를 클라이언트로 보낼 수 있어서 클라이언트와 서버 간의 데이터 통신을 줄일 수 있습니다. 그래서 클라이언트는 필요한 HTML과 JSON만 전달받아 렌더링하면 됩니다. 또한, 서버 컴포넌트는 **보안 측면에서도 강점이 있습니다**. 데이터베이스 연결 정보나 API 키 같은 민감한 정보를 클라이언트로 보내지 않아도 되는 구조라 안전하게 데이터를 다룰 수 있습니다. 리액트에서는 서버 컴포넌트를 클라이언트 컴포넌트와 함께 사용할 수 있도록 설계했습니다. 클라이언트 컴포넌트는 인터랙션이 필요한 UI를 담당하고, 서버 컴포넌트는 데이터 중심의 UI를 담당하는 식으로 역할을 분리할 수 있습니다. 결론적으로, 서버 컴포넌트는 **성능 최적화와 보안 개선, 그리고 개발자 경험 측면에서 많은 이점을 가져다줄 수 있는 기능**이라고 말씀드릴 수 있습니다. ## 서버 컴포넌트의 단점은 없을까요? 🤔 첫 번째로는 **서버 의존성 증가**입니다. 서버 컴포넌트는 이름 그대로 서버에서 실행되기 때문에, 서버가 반드시 필요합니다. 따라서 서버가 다운되거나 응답 시간이 느려지면 클라이언트에서도 영향을 받게 됩니다. 특히, 정적 사이트나 서버리스 환경에서 작업하려는 경우에는 사용할 수 없거나 제약이 있을 수 있습니다. 두번째로는 **사용자 경험**과 **인터랙션 문제**입니다. 서버 컴포넌트는 클라이언트 컴포넌트와 결합해서 사용해야 하는데, 이 과정에서 복잡한 사용자 인터랙션(예: 실시간 업데이트, 드래그 앤 드롭 등)을 처리하기 어렵습니다. 서버 컴포넌트는 주로 정적인 데이터나 렌더링에 적합하기 때문에, 클라이언트 쪽의 인터렉션이 필요한 경우에는 한계가 있을 수 있습니다. ## 📚 추가 학습 자료를 공유합니다. - [리액트 공식 문서](https://ko.react.dev/reference/rsc/server-components) - [React 18: 리액트 서버 컴포넌트 준비하기](https://tech.kakaopay.com/post/react-server-components/)
 

Streaming SSR에 관하여 설명해주세요.

Streaming SSR은 서버에서 렌더링된 HTML을 한 번에 완성해서 보내는 방식이 아니라, 준비된 부분부터 점진적으로 스트리밍해서 클라이언트에 전달하는 기술입니다. 이를 통해 사용자는 페이지의 중요한 콘텐츠를 더 빠르게 확인할 수 있습니다.
기존 SSR은 서버에서 모든 데이터를 처리한 뒤 완전한 HTML을 전송하는 반면, Streaming SSR은 서버가 데이터를 준비하는 즉시 HTML 조각을 스트림 형태로 보내고, 클라이언트는 이를 실시간으로 렌더링합니다. React 18에서는 renderToPipeableStream API를 통해 구현할 수 있으며, 이 API는 서버에서 HTML을 조각 단위로 스트리밍할 수 있도록 지원합니다. 예를 들어, onShellReady 옵션을 사용해 스트림을 응답으로 바로 전송할 수 있습니다.
renderToPipeableStream(<App />, { onShellReady() { res.setHeader('Content-Type', 'text/html'); stream.pipe(res); }, });
이 방식의 가장 큰 장점은 초기 로딩 시간을 단축할 수 있다는 점입니다. HTML의 일부라도 준비되는 즉시 클라이언트가 렌더링을 시작하므로 TTFB(Time to First Byte)가 개선됩니다. 특히 데이터가 많거나 복잡한 대규모 애플리케이션에서 효과적이며, 사용자가 중요한 콘텐츠를 먼저 확인할 수 있어 전반적인 사용자 경험도 향상됩니다. 다만, 클라이언트에서 부분적으로 전송된 HTML을 제대로 Hydration할 수 있도록 설계가 필요하며, SEO나 캐싱 정책과의 호환성도 신중히 고려해야 합니다.
이러한 특징과 장점을 통해 Streaming SSR은 기존 SSR의 한계를 극복하며, 더욱 빠르고 효율적인 웹 페이지 렌더링을 가능하게 만듭니다.
 
  • 스트리밍된 데이터와 리액트의 Hydration 과정에서 발생할 수 있는 문제는 무엇인가요? 🤔
주요한 문제점은 렌더링 되는 HTML과 리액트의 상태 불일치라고 말씀드릴 수 있습니다.
HTML과 리액트 상태의 불일치 문제는 스트리밍된 HTML이 서버에서 먼저 클라이언트로 전송되고, 리액트가 실행되기 전까지는 그냥 정적인 상태로만 보여지는 데서 시작됩니다. 이후 Hydration 과정에서 이 HTML에 리액트의 상태와 이벤트 핸들러가 결합되는데, 이때 서버와 클라이언트 사이 데이터가 맞지 않으면 문제가 생길 수 있습니다.
예를 들어, 서버에서 렌더링된 데이터가 클라이언트에서 Hydration 시점에 변경되어 있다면 리액트가 경고를 띄우거나, 예상치 못한 UI 동작이 나타날 수 있습니다. 또, 비동기 데이터 처리를 Suspense로 하고 있다면, 데이터가 늦게 로드되면서 UI가 달라질 가능성도 있습니다.
 
  • 그럼 이러한 불일치 문제를 해결하려면 어떻게 해야하나요? 🧐
이런 문제를 막으려면, 서버와 클라이언트에서 동일한 데이터 소스를 사용해야 합니다. 예를 들어, Tanstack Query 같은 라이브러리를 활용하면 데이터를 동기화하기가 훨씬 수월해집니다. 또, Suspense와 fallback을 잘 활용하면, 데이터가 아직 준비되지 않았을 때도 안정적인 화면을 보여줄 수 있습니다. 이렇게 하면 사용자 입장에서 데이터가 로드되기 전에 UI가 흔들리는 문제를 줄일 수 있습니다.
매일메일 - Streaming SSR에 관하여 설명해주세요.
`Streaming SSR`은 서버에서 렌더링된 HTML을 한 번에 완성해서 보내는 방식이 아니라, 준비된 부분부터 점진적으로 스트리밍해서 클라이언트에 전달하는 기술입니다. 이를 통해 사용자는 페이지의 중요한 콘텐츠를 더 빠르게 확인할 수 있습니다. 기존 SSR은 서버에서 모든 데이터를 처리한 뒤 완전한 HTML을 전송하는 반면, Streaming SSR은 서버가 데이터를 준비하는 즉시 HTML 조각을 스트림 형태로 보내고, 클라이언트는 이를 실시간으로 렌더링합니다. React 18에서는 `renderToPipeableStream API`를 통해 구현할 수 있으며, 이 API는 서버에서 HTML을 조각 단위로 스트리밍할 수 있도록 지원합니다. 예를 들어, onShellReady 옵션을 사용해 스트림을 응답으로 바로 전송할 수 있습니다. ```js renderToPipeableStream(<App />, { onShellReady() { res.setHeader('Content-Type', 'text/html'); stream.pipe(res); }, }); ```` 이 방식의 가장 큰 장점은 초기 로딩 시간을 단축할 수 있다는 점입니다. HTML의 일부라도 준비되는 즉시 클라이언트가 렌더링을 시작하므로 TTFB(Time to First Byte)가 개선됩니다. 특히 데이터가 많거나 복잡한 대규모 애플리케이션에서 효과적이며, 사용자가 중요한 콘텐츠를 먼저 확인할 수 있어 전반적인 사용자 경험도 향상됩니다. 다만, 클라이언트에서 부분적으로 전송된 HTML을 제대로 Hydration할 수 있도록 설계가 필요하며, SEO나 캐싱 정책과의 호환성도 신중히 고려해야 합니다. 이러한 특징과 장점을 통해 Streaming SSR은 기존 SSR의 한계를 극복하며, 더욱 빠르고 효율적인 웹 페이지 렌더링을 가능하게 만듭니다. ## 스트리밍된 데이터와 리액트의 Hydration 과정에서 발생할 수 있는 문제는 무엇인가요? 🤔 주요한 문제점은 렌더링 되는 HTML과 리액트의 **상태 불일치**라고 말씀드릴 수 있습니다. HTML과 리액트 상태의 불일치 문제는 스트리밍된 HTML이 서버에서 먼저 클라이언트로 전송되고, 리액트가 실행되기 전까지는 그냥 정적인 상태로만 보여지는 데서 시작됩니다. 이후 Hydration 과정에서 이 HTML에 리액트의 상태와 이벤트 핸들러가 결합되는데, 이때 서버와 클라이언트 사이 데이터가 맞지 않으면 문제가 생길 수 있습니다. 예를 들어, 서버에서 렌더링된 데이터가 클라이언트에서 Hydration 시점에 변경되어 있다면 리액트가 경고를 띄우거나, 예상치 못한 UI 동작이 나타날 수 있습니다. 또, 비동기 데이터 처리를 Suspense로 하고 있다면, 데이터가 늦게 로드되면서 UI가 달라질 가능성도 있습니다. ## 그럼 이러한 불일치 문제를 해결하려면 어떻게 해야하나요? 🧐 이런 문제를 막으려면, 서버와 클라이언트에서 동일한 데이터 소스를 사용해야 합니다. 예를 들어, Tanstack Query 같은 라이브러리를 활용하면 데이터를 동기화하기가 훨씬 수월해집니다. 또, Suspense와 fallback을 잘 활용하면, 데이터가 아직 준비되지 않았을 때도 안정적인 화면을 보여줄 수 있습니다. 이렇게 하면 사용자 입장에서 데이터가 로드되기 전에 UI가 흔들리는 문제를 줄일 수 있습니다. ## 📚 추가 학습 자료를 공유합니다. - [renderToPipeableStream 관련 공식 문서](https://ko.react.dev/reference/react-dom/server/renderToPipeableStream)