Home

읽기 설정

만약 당신이 나처럼 생각한다면, 리액트를 사용하면서 때로는 조금 혼란스러울 수 있습니다.00:00

알죠, 한편으로는 레고 블럭처럼 쉽게 조립하는 느낌이 들 수도 있지만, 반대로 '아이템 강력도'와 '순도', '렌더 단계'와 '커밋 단계', 병렬 처리 등과 같은 용어에 직면하게 되면서 무엇을 의미하는지 헷갈리는 부분이 생기기도 합니다.00:05

이 영상에서는 이러한 각 용어들을 살펴보고 싶습니다. 그래서 React 여정에서 이 용어들을 접했을 때 의미를 더 잘 이해할 수 있기를 바랍니다. 첫 번째는 렌더링 단계입니다. 보기나 Angular와 같은 React는 사용자 인터페이스를 렌더하는 라이브러리지만, 렌더링 단계라는 용어를 만났을 때00:22

React는 앱을 그려내기 위한 작업을 두 단계로 나눕니다. 첫 번째 단계는 '렌더링' 단계이며, 여기에서 React는 모든 구성 요소를 실행하고 JSX 트리 결과를 얻습니다. 처음으로 React가 앱을 렌더링하는 경우00:41

그냥 전체 JSX 트리를 반환할 뿐이지만, 대부분의 렌더링과 같이 업데이트라면 새 JSX 트리와 이전 트리를 비교하고 차이점을 계산하는 것입니다. 이 과정을 재조합이라고 합니다. Git가 저장소의 두 개의 스냅샷을 비교하는 것과 마찬가지입니다.00:59

그리고 차이점을 계산합니다. 어쩌면 역설적이지만, 렌더링 단계는 화면에 실제로 픽셀을 그리는 것보다는 이러한 차이를 계산하는 데 중점이 있습니다.01:19

그게 렌더링의 두 번째 단계인 커밋 단계에 대한 거죠.01:28

그래서 현재 DOM을 살펴보고 h1 태그를 추가해야 한다는 것을 알아내는데, 현재에는 없으므로 document.createElement를 호출하여 두 트리의 일치를 이룹니다. 따라서 커밋 단계는 현재에 시각적 업데이트를 적용하는 데 모두 관여합니다.01:39

웹사이트에서도 다시 한번 diff 덕분에 React는 DOM을 업데이트하는 방식이 정말 지능적으로 될 수 있죠. 우리 개발자들은 여전히 코드를 선언적으로 작성하면서 시간이 지남에 따라 무엇이 변하고 무엇은 동일하게 유지되는지를 추적하지 않아도 됩니다.01:55

그래서 리액트가 우리 앱의 어떤 부분이 시간이 지남에 따라 변경되는지 실제로 알아차이는 건 어떻게 하는 걸까요? 여기서 상태(state)가 들어옵니다. 상태는 실행 중인 데이터이고, 리액트가 애플리케이션을 렌더링하기 위해 의존하는 데 사용됩니다. 이 데이터는 시간이 지남에 따라 변경되며 일반적으로 우리 앱의 시각적 출력에 영향을 미칩니다. 그러나 다른 데이터도 있습니다.02:11

시간이 지남에 따라 변하는 것은 우리 애플리케이션의 일부이지만 React 상태의 일부는 아닙니다. 스크롤 위치나 마우스 위치, 초점을 받고 있는 요소 또는 브라우저에서 강조 표시된 텍스트와 같습니다. 브라우저가 이러한 데이터를 추적하지만, 그가...02:32

React 내부에서 또는 애플리케이션의 재렌더링을 트리거하는 것은 React 상태가 아니라 우리의 상태입니다. React를 통해 정의할 수 있으며, React는 업데이트하려면 호출할 수 있는 함수를 제공합니다. 이 업데이터는 애플리케이션의 재렌더링을 트리거하는 주된 방법이며, 상태는 02:49

react가 반응적이게 만드는 바로 그 핵심 요소이고, 상태의 결과물로서 부작용이 생겨요. render 함수의 목표는 react가 사용해서 diff를 계산하고 마침내 웹 페이지에 적용할 수 있는 JSX를 돌려주는 거죠. commit 단계에서 말이죠. 그렇다면 컴포넌트 안의 다른 코드들은...03:09

JSX를 만들거나 조작하는 데 직접적으로 관련 없는 부분은 부작용으로 간주될 수 있습니다.03:29

API에서 데이터를 가져오거나 문서 제목을 업데이트하거나 심지어 콘솔 로그를 기록하는 것조차도 부작용의 예입니다.03:35

이제 리액트 내에서 사이드 이펙트가 무엇인지에 대한 몇 가지 뉘앙스를 이야기할게요. 일부 개발자들은 이에 대해 동의하지 않을 수도 있지만, 일반적인 규칙으로는 리액트 애플리케이션에 대해 말할 때 JSX를 생성하거나 조작하지 않는 코드는 대부분 사이드 이펙트라고 간주할 수 있어요. 알겠죠? 그 다음은...03:43

흥미롭고, 이 하나는 순수성입니다. 만약 당신이 React를 꾸준히 작성해 온다면 'render 함수는 순수해야 한다' 라는 말을 들었을 것입니다. 하지만 그 의미가 무엇인가요? 요컨대 순수한 함수를 정의하는 한 가지 방법은 부작용이 없고, 출력이 입력에만 의존하는 함수입니다.04:04

지금 '부작용'과 '순수성'이라는 개념은 일반적인 프로그래밍에도 적용되지만, 이 영상에서는 이전 섹션에서 논의했던 것처럼 부작용을 생각해 보세요.04:23

구독 설정, 로그 기록, DOM을 수동으로 조작하거나 API에서 데이터를 가져오는 것과 같이.04:35

그리고 이것이 바로 렌더 함수에 새 날짜를 쓰는 것조차도 당신의 렌더 함수가 불순함을 가져온다. 만약 같은 상태와 props 세트로 반복적으로 실행한다면, 새로운 날짜는 불순물이며 매번 다른 결과를 돌려줄 것이다.04:49

우리가 설명하는 순수함을 기억해주세요. 순수 함수는 같은 입력 값에 대해 항상 동일한 출력을 반환해야 합니다. 그러므로 여러분이 생각하실 수도 있어요, '저는 애플리케이션에서 부작용을 해야 하는데? 데이터를 가져오거나 저장하거나 심지어 날짜를 표시해야 하는 상황이에요. 이건 어떻게 할까?'05:06

컴포넌트에서 사용 효과를 사용하면 렌더 함수에서 불필요한 부분을 제거하는 거예요. 즉, 사이드 이펙트를 JSX 계산과 분리하여 표시하고, 리액트가 모든 사이드 이펙트를 순서대로 대기시키고 실행할 수 있게 해줍니다.05:23

그것들을 스스로의 조건으로 처리하지만, 그 자체가 순수해야 합니다. 이는 모든 것이 올바르게 작동하고 우리가 앞으로 이야기할 새로운 기능을 활용하도록 하기 위해 React에서 가정하는 종류입니다. 하지만 첫째, 한 가지 더 중요한 개념이 있습니다. 그것을 '일관성'이라고 부릅니다.05:43

이제 또 다른 용어인데요, 특정 종류의 함수가 그 함수의 부작용과 관련된 방식을 설명하는 거예요. 효과적인 함수라 불리는데, 이런 함수는 부작용이 여러 번 호출될 때마다 전체 시스템 상태에 동일한 영향을 미치는 함수죠. 제 생각에는...06:01

이것을 가장 잘 설명하는 방법은 예시를 들어 보여드리는 것입니다. 그러므로 데이터베이스 시드 작업 경험이 있으신다면 배포할 때 호출되는 시드 함수 작성에 익숙하실 수 있습니다. 예를 들어 국가 목록 테이블이 있는 애플리케이션을 만들고 있다고 가정하면 사용자가 드롭 다운 메뉴에서 볼 수 있도록 합니다. 애플리케이션을 처음 배포할 때, 시드 파일을 실행하는 것입니다.06:20

그리고 미국이라는 나라를 만들었잖아요. 이제 앱에 변경사항을 적용하고 다시 배포하면, 매번 배포할 때마다 그 시드 파일을 실행하고 싶죠? 어떤 환경에서든 앱이 작동하도록 하기 위해서죠. 하지만 미국처럼...06:40

아메리카가 한 번 더 나타났다면 당신이 데이터베이스 테이블에 두 번 넣고 싶지 않을 거예요. 그래서 함수를 항등함수로 만들죠. 처음으로 미국이 테이블에 없으면 삽입하고, 있으면 괜찮다는 거죠. 이것이 바로 항등성입니다.06:56

씨드 함수가 이제 공리적이라고 하는데, 다시 말해 여러 번 실행해도 괜찮다는 거예요. 한번 실행하든 20번 실행하든 마지막 결과는 데이터베이스 테이블의 국가 목록과 같겠죠? 리액트 맥락에서 우리는 주로 사이드 효과가 공리적이어야 한다고 말하는데.07:14

그리고 이것이 바로 useEffect가 우리에게 정리 함수를 제공해주는 이유입니다. 예를 들어, 우리가 useEffect 안에 부작용을 넣고 구독을 설정한다면, 반드시 그 구독을 해제해야 합니다.07:31

그 페이지나 컴포넌트가 언마운트될 때, 스스로 정리해야 합니다.07:45

이렇게 React를 사용하면 컴포넌트를 Mount, Unmount 그리고 다시 Mount할 수 있어요. 그래서 우리 애플리케이션에 20개의 구독이 생기지 않죠. 따라서 잘 작동하는 React 컴포넌트와 React 애플리케이션을 만들고 싶다면 이러한 원칙을 따르는 게 중요해요: 07:49

컴포넌트는 동일한 결과를 반환하도록 설계되어 있어요. 다시 말해서, 우리 측의 부작용을 여러 번 실행해도 시스템 상태에 문제가 발생하지 않아요. 새로운 구독(20개 등)이 생기지 않는다는 거예요. 우리가 자원 정리 작업을 잘 해내고 있다면, 같은 작업들을 반복해서 수행할 수 있어요.08:05

마치 우리 데이터베이스에서 보는 씨앗 파일처럼 알겠죠? 그 다음으로 말씀드리고 싶은 것은 휴리스틱이며 물론 이것은 일반적으로 지침이나 원칙이라는 의미입니다. 하지만 React 개발팀이 React에 대해 이야기할 때, 특히08:21

리액트 18에 오는 새로운 기능들08:38

리액트로 성공적으로 작업하고 싶거나, API 디자이너의 의도대로 사용하려면 따를 수 있는 가이드라인 또는 원칙인 휴리스틱스가 기본적으로 필요합니다.08:40

React는 우리 컴포넌트에서 주변 효과를 결정론적으로 찾을 수 없기 때문에, 우리가 주변 효과를 이해하여 사용할 수 있는 `useEffect`에 넣고, 동일한 결과를 항상 가져오도록 만들어 재렌더링 과정에서 문제가 생기지 않도록 하는 것이 중요해요.08:52

다시 한 번. 다시 하고 이것은 바로 렌더링이 순수하고, 렌더링이 불변하는다는 유연성의 원칙으로 돌아옵니다. 지금은 따르는 것이 필요하니까 조금 이상하게 느껴질 수 있습니다. 때때로 이 규칙을 위반하거나 유연성을 따르지 않고 렌더 함수에 약간의 불순물이 있을 수도 있으며, 어플리케이션이09:08

괜찮아요. 아마 당신이 코드에 버그가 없거나 이상한 점이 없는 것을 보지 못하실 텐데, 우리 팀은 오랫동안 이를 가정하고 있고 React 관련 문서와 교육 자료에서도 언급되어왔습니다. 다시 한번 React 팀에게09:26

and the library more power in the future if they can assume everyone's render functions are pure they can do all sorts of cool stuff with our applications that we haven't even thought about yet and that that's what we're going to talk about next so you might be wondering what does render09:43

and commit and item potence and purity kind of all have in common why are these things related why are we talking about them well the answer is react 18 and this leads us to our final term which is concurrency so if you've heard about suspense or transitions or interruptible rendering09:58

or scheduling you've been hearing about concurrent react which is a set of features that's coming to react 18. so what does it mean what does concurrent react mean well in react 17 rendering is synchronous so react only has synchronous rendering and what synchronous rendering means is the moment a render10:17

처음 렌더링 또는 업데이트에서 시작되며 React가 실행을 시작하는 렌더링 단계는 아무것도 중단할 수 없습니다. 렌더링이 시작된 시점부터 브라우저에 업데이트를 실제로 적용하기까지의 시간 동안 발생할 수 있는 모든 작업은 중단될 수 없습니다.10:38

그냥 직선상에서 끝날 때까지 일어나지만, 비동기적 리액트에서는 그렇지 않습니다. 따라서 리액트는 업데이트가 있음을 알 수 있으며 렌더링 단계에서 이미 해당 업데이트를 준비하기 시작합니다. 새로운 JSX 트리 계산과 차이점 분석을 하고, 다른 작업이 일어나면서도...10:54

DOM에 업데이트를 실제로 적용하기 전에 그 작업이 중단될 수 있도록 렌더링을 방해할 수 있다는 것입니다. 즉, 이것이 방해 가능한 렌더링이라는 의미이며, 이렇게 하는 이유는 모든 작업을 분할하는 데 있어 더욱 지능적일 수 있기 때문입니다.11:12

예를 들어 사용자가 입력창에 글씨를 치고 있을 때, 그 순간에 큰 그래프를 다시 표시해야 할 수 있어요. 그러면 렌더링 및 커밋 단계가 시작되죠.11:29

하지만 가끔은 많은 작업이 필요할 수도 있어요. 렌더링 단계에서 새로운 트리 계산하는 데 많은 노력이 들고 브라우저가 때때로 멈추기도 합니다. 그러므로 React가 이 두 부분을 분리한다면 작업을 시작할 수 있지만, 사용자가 입력창에 글자를 치는 등 우선순위가 높은 업데이트에 제어권을 주기 위해 종종 일시적으로 중단하는 거예요.11:39

필드는 항상 반응성이 느껴져야 합니다. 그리고 사용자가 입력을 하면 새로운 쿼리가 생성되고 React가 이전에 준비한 그 트리를 더 이상 필요하지 않다고 결정합니다. 시작부터 다시 쌓아나가세요. commit 단계를 거치지 않고 바로 새롭게 시작하는 것입니다. 이것이 스케줄링 부분이며, React 18 앱을 훨씬 더 빠르고 강력하게 만드는 요소입니다.11:59

요런 무거운 로딩 상황을 생각해보면 렌더링이 순수해야 하는 이유가 이해되죠. react는 모든 컴포넌트가 순수하다는 가정을 하고 있기 때문에, 실행하면 단순히 순수 계산만 수행한다고 가정하는 거예요. 입력값을 받아...12:21

JSX 트리 계산하는 거지, 그거만 하고 외부 효과는 없어. 어떤 글로벌 상태도 변형하지 않고 세상을 아무런 방식으로 바꾸지 않아. 만약 그 가정이 맞다면, React는 같은 시점에 우리 앱의 다른 버전들을 렌더링할 수 있어요, 업데이트 없이 말이죠.12:41

실제 브라우저로 넘어가자면, 또 다른 화면을 준비하고 싶다고 가정해 보세요.12:57

모달 마법사와 같은 경우에 새로운 화면을 스와이프로 가져오고 싶다면 React는 그걸 백그라운드에서 미리 준비할 수 있어서 사용자가 '다음' 버튼을 클릭하면 바로 애니메이션으로 들어갈 수 있도록 하죠.13:02

그들이 그것을 클릭하기를 기다리지 않고 DOM을 조작하는 것은 가능합니다. 아니면 화면 밖에 준비된 것을 사용하여 '우리는 이게 필요 없어'라고 결정할 수도 있습니다.13:14

그들이 취소를 누르면 그냥 사라지고, react는 기본적으로 우리 앱의 여러 개의 복사본을 메모리에 표시할 수 있다는 점이 중요해. 그리고, 이 모든 과정에서 우리 컴포넌트가 순수하다는 것을 가정해야 해.13:21

저곳에서 작업할 때는 이미 스스펜스와 리액트 18의 전환 효과와 같은 멋진 기능들이 있습니다. 자세한 내용은 발표 블로그 게시물을 읽어보시면 됩니다. 오늘부터 사용하실 수 있으며 이 기능에 의존합니다. 그리고 더욱 정말 훌륭한 기능들이 앞으로 출시될 예정입니다. 리액트 계정에서...13:36

화면 밖 구성 요소에 대한 트윗을 보는데, 내가 설명한 것과 비슷해요. 사용자가 사이트에서 탭을 벗어나더라도 애플리케이션의 일부를 해제하거나 숨기고 메모리를 절약하거나 구독을 정리할 수 있죠. 그리고 다시 돌아오면 React가 그 메모리를 기억하는 거예요.13:52

그냥 화면으로 바로 다시 전달할 수 있어요. 그래서 최신의 동시 실행 React 기능을 사용하려면 렌더링이 순수해야 해요. 바로 이런 이유 때문에 요즘 이러한 개념들이 정말 중요해지죠. 만약 React 18에 접어들었다면 '엄격 모드'라는 용어를 들어본 적 있겠네요. 엄격 모드는 말이죠.14:07

리액트 17에서 18으로 가면 조금 변화가 있지만, 기본적으로 우리가 아직 이야기하고 있는 주제와 관련이 있어요. 당신이 순수한 컴포넌트를 작성하도록 도와주려는 것입니다. 예를 들어 스트릭 모드는 컴포넌트를 처음 render할 때14:23

모든 것을 마운팅하고, 그로 인해 컴포넌트가 생성되고, `useEffect`와 `useLayoutEffect`를 사용하는 것입니다. 즉시 언마운팅을 시뮬레이션하며 모든 효과의 청소 함수가 실행됩니다. 그리고 다시 마운팅을 시뮬레이션하면서...14:39

그 당시 상태와 관계없이 같은 효과를 다시 만들어 낼 거예요. 따라서 업데이트될 때마다 하나의 구독만 생성하는 구성 요소들이 있다면 자신들의 작업을 정리하지 않는 경우 문제가 생길 수 있습니다. 하지만 중요한 것은 ...14:55

이 버그들은 병렬적인 React 패턴과 관련되어 있기 때문에, 불필요한 부분을 제거하고 효과를 동일성 유지하는 방식으로 만들어야 합니다. 그렇게 하면 구성 요소와 앱이 React 18에서 제공되는 모든 멋진 기능을 활용할 준비가 될 것입니다.15:11

그래서 오늘 이야기하고 싶은 건 바로 이거죠. React를 배우는 동안 순수성과 공역(idempotence) 같은 용어들을 접했는데 처음에는 그 의미를 깊이 있게 배우려고 시간을 내지 않았죠. 우리 모두 바쁘니까 할 일 목록 아이템을 화면에 표시하는 것에 집중하고 있어서 특정 영역에 더 깊이 들어가야 할 때를 결정해야 하는 거죠.15:26

우리에게는 많이 알지 못하고 불편한 부분들이 있지만, 특히 React 팀이 Concurrent 모드에서의 React 18에 대해 이야기하는 것을 보면서 계속 등장했어요. 어느 정도 이것들이 구현 세부 사항이고 기술적인 자세들은 React 뒤에 숨겨져 있다고 생각하지만.15:46

우리 React 개발자로서 이러한 개념을 이해하는 것은 중요합니다. 왜냐하면 이것들이 라이브러리의 의도된 사용 방식이며, 잘 작동하는 구성 요소를 작성하고 새로운 기능을 모두 활용하여 우수한 성능을 보이는 React 애플리케이션을 만들도록 도와주기 때문입니다.16:04

우리가 이전에는 앱의 새로운 버전을 백그라운드에서 준비할 수 있는 오프스크린 구성 요소에 대해 생각하지도 않았어요. 하지만 이 가이드라인과 휴리스틱을 따르면 미래에 그 기능을 활용할 수 있을 거예요. 따라서 도움이 되었으면 좋겠어요. 확인하세요.16:20

아래 설명에 링크가 있는데요, 이 비디오를 준비하면서 읽었던 자료 중 몇 가지 링크를 추가했습니다. 하나는 React 코어 팀원이 작성한 React 규칙으로, 사양서처럼 구체적인 내용을 담고 있습니다. 읽으면서 어떤 점을 느낄 수 있도록 구성되어 있어요.16:35

이 영상에서 우리가 많이 이야기하는 내용들에 대해서이고, React Advanced Guides 같은 공식 문서에서 조금 더 자세한 기술적인 설명도 있어요. Reconciliation 등을 좀 더 자세히 알고 싶다면 참고하면 좋겠죠? 전 잘 도움이 될 수 있었으면 하는데, 이렇게까지 보셨다니 정말 감사합니다! 다음 영상에서 만나요. 안녕.16:50

AI Summary

이 영상은 React 18의 동시 실행 기능을 제대로 활용하기 위해 React 개발자들이 렌더링의 순수성과 공역성을 이해해야 한다고 강조합니다. React 18은 렌더링을 중단하고 재개할 수 있는 기능을 제공하여 사용자 인터페이스 응답성을 높이고 백그라운드 작업을 효율적으로 처리할 수 있습니다. React 팀은 개발자들이 순수 렌더링을 한다는 가정을 기반으로 기능을 개발하고 있으므로, React 18의 모든 기능을 활용하려면 순수 렌더링 원칙을 준수하는 것이 중요합니다. 엄격 모드를 활용하여 잠재적인 문제를 발견하고, React 규칙과 공식 문서를 참고하여 더 깊이 있는 학습을 하는 것이 좋습니다.

Key Highlights

  • React 18은 렌더링을 중단하고 재개할 수 있는 동시 실행 기능을 제공하여 사용자 인터페이스 응답성을 향상시킵니다.
  • 렌더링 함수는 외부 상태를 변경하지 않고 입력값만 받아서 출력(JSX 트리)을 생성해야 하는 순수해야 합니다.
  • 동일한 입력에 대해 항상 동일한 출력을 생성하는 공역성은 React 18의 효율적인 동작을 위해 중요합니다.
  • 엄격 모드는 개발자가 순수 컴포넌트를 작성하도록 돕고 잠재적인 부작용을 검사합니다.
  • React 팀은 개발자들이 순수 렌더링을 한다는 가정을 기반으로 기능을 개발하고 있습니다.

Related Videos