본문 바로가기
FE/react

[React] 일방향 흐름 (One-Way Data Flow)

by 빠니몽 2024. 3. 1.

03.01.2024

0. Background

리액트에서의 데이터 흐름은 단방향이고, 단방향이어야 한다.

즉, 부모 컴포넌트로부터 자식 컴포넌트로 전달된다.

이것을 우리는 일방향 흐름 또는 단방향 흐름(One-Way Data Flow)라고 한다.


1. Reactivity

Reactivity, 한국말로 반응. 이것은 무엇을 뜻할까? 감히 정의를 해보자면

Reactivity: 애플리케이션의 내부적인 상태를 실제 UI에 반영하는 규칙

 

이라고 할 수 있다.

 

이 Reactivity, 반응이라는 개념에서는 알아두어야 할 핵심 두 가지가 있다.

  • 흐름(Flow): 물이 고이면 안된다
  • 일방통행(One-Way): 물이 역류해서는 안된다.

2. 대표적인 안티패턴

2-1. 건전하지 않은 의존성 배열

우리는 먼저 의존성 배열(Dependency Array)에 대해 알아보아야 한다.

의존성 배열이란 useEffect, useCallback, useMemo 등의 훅에서 사용되는 배열이다.
훅이 불필요하게 반복해서 실행되는 것을 방지하며, 성능을 최적화 하기 위해서 사용한다.

 

리액트를 써 본 분들이라면 쉽게 떠올릴 수 있을 것이다.

 

"아 그 useEffect에 넣는 배열!"

 

맞다 ㅋㅋㅋㅋ 해당 훅이 실행되는 조건과 같은 역할을 한다.그렇다면 건전하지 않은 의존성 배열은 무엇을 뜻할까?의존성 배열을 사용할 때 조심해야할 점이 몇 가지 있긴 하지만, 현재의 맥락에서 살펴보자면의존성 배열이 원시타입이 아닐 때 상태가 고이는 것을 주의해야 한다는 뜻같다.

 

의존성배열에 있는 값들에 변화가 감지될 때마다 훅들이 실행되는데, 만약 의존성배열에 오브젝트 타입의 값들이 들어가있다면, 그 오브젝트의 값이 아닌 주소가 바뀌어야만 훅이 실행이 가능하다.

이 사실을 모른다면 일방향 흐름을 고수해야 하는 리액트에서 상태가 흐르지 않고 고여있게 된다.

그 외에 useReducer나 useRef를 사용하여 의존성 배열을 최소화 하는 방법은 다음 글을 참조하기 바란다.

https://velog.io/@ksh4820/useEffect-%EC%9D%98%EC%A1%B4%EC%84%B1-%EB%B0%B0%EC%97%B4-%EA%B4%80%EB%A6%AC-%EB%B0%A9%EB%B2%95

 

useEffect 의존성 배열 관리 방법

useEffect 의존성 배열 관리 방법 의존성 배열은 useEffect 훅에 입력하는 두 번째 매개변수이다. 의존성 배열의 내용이 변경되었을 경우 부수 효과 함수가 실행된다. 의존성 배열은 잘못 관리하면 쉽

velog.io

2-2. 자식이 상태를 조작하는 것처럼 보이는 네이밍

상태는 무조건 부모에게 조작권이 있어야한다.

자식은 부모에 "이벤트 핸들러"를 노출할 수 있을 뿐, 상태를 자식에서 부모로 올려보내면 안된다.

2-3. 불필요한 상태 동기화

동기화의 필요성: 상태가 일시적으로 최신화되지 않고 고여있으면 상태의 일관성을 보장할 수 없으며 성능에 악영향을 미침

상태를 동기화하지 않고 계산을 하면 된다.

서로 엮여있는 상태가 많다면 useReducer를 사용할 수도 있다. (위 블로그 참고)


3. Reactivity Cheat Sheet

현대적인 프레임워크들 사이에서 핫한 주제이다.

이벤트핸들러가 있을경우 또는 많을 경우, 이러한 Reactivity를 잘 지키는 방법이 있을까?

100퍼센트 완벽한 구현법이란 없겠지만, 대부분에 경우에 적합한 치트키와 같은 방법은 있다.

  1. 구현하고 싶은 것을 먼저 순방향으로 구현을 해보자
  2. 그 다음 역방향(이벤트의 전파, 세터에 도달할 때 까지의 전파)을 구현해보자 
  3. 체크리스트를 확인하여 위배되는 것이 없는지 확인하자

체크리스트

1. 값의 변화가 잘 맞게 동작하는가
2. 자식이 부모의 상태를 변경(역류)하지 않는가

 


4. 결론 

리액트의 기초와 같은 내용임에도 불구하고 한 번도 제대로 정리한 적이 없다는 게 부끄러웠다.

개발을 시작하면 자연스럽게 익히게 되는 규칙이지만 구현이나 구조가 복잡해질 수록 까먹기 쉬운 내용들이라고 생각한다.

체크리스트를 유념하고 복잡한 구현에서도 위배하지 않으며 좋은 코드를 생산하고 싶다.