리액티브 프로그래밍

HELLO WORLD🙌·2020년 12월 16일
1

Memo

목록 보기
7/7

리액티브프로그래밍

필요한 데이터를 획득하기 위해서 애플리케이션이 외부 환경에 요청하여 데이터를 획득하는 것이 아니라, 애플리케이션은 외부 환경을 관찰하고 있다가 외부 환경에서 데이터 스트림을 방출하면 그것에 반응하여 데이터를 획득하는 것이다.

외부 환경에서 애플리케이션 내부로 연속적으로 흐르는 데이터, 즉 데이터 스트림을 생성하고 방출하는 객체를 옵저버블(Observable)이라 하고, 옵저버블이 방출한(emit) 노티피케이션(Notification: 옵저버블이 방출할 수 있는 푸시 기반 이벤트 또는 값)을 획득하여 사용하는 객체를 옵저버(Observer)라 한다. 다시 말해 데이터 소비자(Data consumer)인 옵저버는 데이터 생산자(Data producer)인 옵저버블을 구독(subscription)한다. 이 구독에 의해 옵저버는 옵저버블에 연결되어 옵저버블의 상태를 관찰한다. 그리고 옵저버블이 방출한 노티피케이션은 옵저버에게 자동으로 전파된다.

리액티브 프로그래밍

리액티브 프로그래밍은 말 그대로 '바로 응답하는 프로그래밍'을 말한다. 엄격하게 따지면 리액트는 리액티브 프로그래밍 패러다임에 완벽하게 부합하지는 않지만 '사용자의 요청에 바로 응답하는' 이 핵심 개념에는 부합한다.

리액트는 props를 사용해서 상태(데이터)의 변화를 전파시키는데 이러한 상태 전파 또는 전이는 사용자의 지속적인 요청에 바로 응답할 수 있게 만들어준다. 또 리액티브 프로그래밍의 특징 중 하나인 '유연성' 또한 가지고 있다. 데이터의 변화에 따라 지속적으로 랜더링될 때 일부 데이터가 없거나 비정상적인 데이터를 에러로 처리하지 않고 유연하게 처리한다. 리액트는 옵져버블, 스트림 같은 복잡한 개념 없이 상태를 자식 컴포넌트에 내려주고 상태를 변경에 따라 랜더링함으로서 자연스럽게 '바로 응답하는 프로그래밍'을 구현할 수 있게 해준다.

  • 리액트는 리액티브 프로그래밍이라고 할 수는 없다. 응답성(responsive), 유연성(resilient), 신축성(elastic), 그리고 메시지 주도(message driven)을 모두 갖고 있어야 리액티브 프로그래밍이라고 할 수 있다. 리액트에 RxJS를 더해서 이용하면 완벽하게 리액티브 프로그래밍을 구현할 수 있다. 이렇게 하면 옵져버블을 이용해 데이터 스트림을 다룰 수 있다.

왜 리액트를 쓰나요?

  • 옵져버블 없는 리액티브 프로그래밍

    UI는 사용자와 끊임없이 상호작용합니다.사용자의 입력에 따라 어플리케이션의 상태가 변화하고, 변화된 상태에 따라 화면이 변화합니다.상태와 화면, 이 둘은 변화하는 값(Value over time)입니다.

    변화하는 값들은 다루기 어렵습니다.값의 변화에 맞추에 관련된 다른 것들도 변화시키기 위해 항상 예의주시해야 하기 때문입니다.하지만 사람들은 여기서 포기하지 않고, “값의 변화를 스스로 전파시키게 하면 된다.” 라는 아이디어에 기반해 리액티브 프로그래밍이라는 프로그래밍 패러다임을 고안해 냈습니다.리액티브 프로그래밍(Reactive Programming)은 옵져버블(Observable)과 여러 개념들을 사용해 변화하는 값들을 훌륭히 다룹니다.하나의 예시를 보여드리자면, 이렇게요.

    NOTE:옵져버블, 스트림(Stream). 이 두 용어는 동의어입니다. 리액티브 프로그래밍 커뮤니티는 어떤 단어를 쓰든 같은 의미라고 보지요.

    import { fromEvent } from 'rxjs';
    import { map } from 'rxjs/operators';
    
    const inputElement = document.getElementById('textInput');
    const input$ = fromEvent(inputElement, 'change'); // inputElement에서 'change' 이벤트가 발생할 때 마다 그 이벤트를 자신의 구독자(subscriber)에게 전달하는 옵져버블을 만듭니다.
    const text$ = input$.pipe(map(event => event.target.value)); // input$가 값을 전달할 때 마다 주어진 함수를 이용해 그 값을 변형시킨 후 다시 전달하는 옵져버블을 만듭니다.
    
    text$.subscribe(console.log); // text$ 옵져버블이 전달한 값을 출력합니다.
    

    짜잔, 리액티브 프로그래밍을 하면 이렇게 데이터 플로우를 선언하여 비동기, 동기 할 것 없이 변화하는 값들을 쉽게 다룰 수 있습니다.듣기에는 정말 좋아 보이지만, 리액티브 프로그래밍에도 몇몇 문제가 있습니다.먼저, 가장 큰 문제는 프로그래머가 옵져버블 간의 구독(subscription)에 많이 신경써야 한다는 점 입니다.시그널(singal) 옵져버블이 아닌 이벤트(event) 옵져버블 들은 구독 되는 시점이 중요하고, 그 옵져버블이 어떤 종류(hot/cold/warm)의 옵져버블이냐에 따라 구독이 만들어내는 결과가 달라지기 때문입니다.이는 옵져버블과 옵져버블의 주위 환경을 프로그래머가 다룸으로서 생기는 문제로, 리액트는 옵져버블과 옵져버블의 주위 환경을 감춤으로서 이 문제를 해결했습니다.즉, 간단하게 표현하면 리액트는 다음과 같이 구성된 것 입니다.

    import React from 'react';
    
    function MyComponent() {} // 여기에 우리가 작성한 멋진 컴포넌트가 있다고 상상하세요.
    
    const element$ = props$.map(MyComponent) // props 들의 옵져버블이 props를 전달할 때 마다 그 props를 가지고 컴포넌트를 호출합니다. 결과적으로 props들의 옵져버블을 리액트 엘리먼트들의 옵져버블로 만듭니다.
    element$.subscribe(React.renderReactElement); // 리액트 엘리먼트들의 옵져버블을 구독해, 리액트 엘리먼트들이 전달될 때 마다 화면을 새로 랜더링합니다.
    

    우리의 컴포넌트는 옵져버블이니 구독이니, 복잡한 개념들을 생각하지 않고 주어진 데이터를 가지고 어떻게 랜더링할 것인가만 생각하면 됩니다.왜냐하면 리액티브 프로그래밍과 관련된 복잡한 일들은 리액트가 전부 대신 해주기 때문이죠!

1개의 댓글

comment-user-thumbnail
2021년 1월 6일

잘 보고 있습니다~

답글 달기