Insightr3f-issues

[R3F] react-three-fiber는 왜 이렇게 설계됐을까?

2026-02-05
ReactR3FIssue

0. 토론한 내용 톺아보기

(2) 이 내용은 무엇을 말하는가

이 이슈는 사용법 질문처럼 보였지만, 실제로는 렌더링 패러다임의 충돌을 다루고 있었다.

  • Three.js : 명령형 (imperative)
  • React : 선언형 (declarative)

질문자는 Three.js의 사고방식으로 React의 도구를 사용하려 했고, 그 과정에서 자연스럽게 혼란이 생긴 것이다. react-three-fiber는 이 지점에서 명확한 기준을 제시한다.

구조는 선언적으로, 동작은 필요할 때만 명령적으로

react-three-fiber가 의도한 사용 방식

위의 문장을 조금 더 풀어보면, react-three-fiber가 의도한 역할 분담은 다음과 같다.

1️⃣ 선언적으로 관리하는 것 - React의 영역

  • 씬에 무엇이 존재하는지
  • 오브젝트의 계층 구조는
  • position/rotation/scale 같은 정적인 상태
지금 이 상태라면, 씬에는 이런 구조가 존재해야 한다
1
지금 이 상태라면, 씬에는 이런 구조가 존재해야 한다
{boxes.map(box => (
  <mesh key={box.id} position={[box.x, 0, 0]}>
    <boxGeometry />
    <meshStandardMaterial />
  </mesh>
))}

➡️ 이는 "mesh를 추가해라"라는 명령이 아니라 존재해야한다는 선언이다.


2️⃣ 명령적으로 다루는 것 - Three.js의 영역

반면, 다음과 같은 작업들은 선언형 모델에 잘 맞지 않는다.

  • 매 프레임마다 바뀌는 값
  • geometry 직접 수정
  • shader uniform 업데이트
  • 물리 연산, 애니메이션 루프

이런 경우에는 ref, useFrame, onUpdate 같은 명령형 탈출구를 사용하도록 설계되어 있다.

즉, r3f는 명령형 API를 금지하지 않는다.
1
즉, r3f는 명령형 API를 금지하지 않는다.
const ref = useRef()
 
useFrame(() => {
  ref.current.rotation.y += 0.01
})

다만, "씬의 구조를 명령으로 관리하지 말자"는 선을 긋고 있을 뿐이다.


1. 왜 D3 같은 모델을 선택하지 않았을까?

질문자가 기대했던 방식은 D3에 가깝다.

data -> scene
1
data -> scene
data 변경 -> 직접 scene 수정 -> 화면 반영

하지만 r3f는 이 방식을 선택하지 않았다. 그 이유는

React의 핵심 전제가 "UI는 상태의 결과"이기 때문이다.


먼저, React는 "변경"을 어떻게 처리할까?

React에서 상태가 바뀌면 화면이 바뀐다는 것은 쉽게 알 수 있다.
하지만 여기서 우리가 알아야 할 건 React는 바로 화면을 고치지 않는다는 점이다.

대신 이렇게 질문한다. "이전 화면과 지금 화면은 정확히 무엇이 달라졌을까?"
이 질문에 답하는 역할이 바로 Reconciler이다.

2. Reconciler의 역할 - "무엇이 바뀌었는지 계산하는 엔진"

React 업데이트가 발생하면, Reconciler는 다음 순서로 동작한다.

⚠️ React 업데이트가 일어나면

  1. 컴포넌트를 다시 실행해 새 React Element 트리를 만들고
  2. 이전 트리와 비교(diff)해서
  3. 무엇을 추가/삭제/이동/업데이트 해야 하는지를 작업 목록으로 정리한다.

그렇다면 실제 화면은 누가 바꿀까?

  • Reconciler가 만든 "작업 목록"을 실제로 DOM이나 화면에 적용하는 주체가 필요하다.
  • 이 역할을 맡는 것이 Renderer다. React는 이 과정을 2단계로 나눈다.

3. React 업데이트는 왜 두 단계로 나뉠까?

이 분리는 성능과 사용자 경험을 위해 존재한다. 공식 문서 참고

A. Render Phase (Reconciliation Phase)

  • 컴포넌트들을 호출(렌더링)해서 새 트리를 만들고
  • 이전 트리와 비교해서 “이렇게 바꿔어야 한다”을 계산만 수행한다.

중요 : 이 단계는 중단/재시작/폐기가 가능하다.

B. Commit Phase

  • render phase에서 만든 “작업 목록”을 실제 DOM/호스트에 동기적으로 한 번에 적용
  • 이때 effect(lifecycle, layout effect 등)도 함께 처리

4. Fiber는 왜 등장했을까? - “중단 가능한 렌더링을 가능하게 만든 구조”


5. React는 어떻게 Three.js를 렌더링할 수 있을까?

React는 공식적으로 Custom Renderer를 만들 수 있도록 react-reconciler 패키지를 제공한다.

이 패키지는 Reconciler와 특정 플랫폼을 연결하는 브릿지다.

핵심 개념: Host Config

  • Reconciler는 ‘무엇을 바꿀지’를 계산하고
  • Renderer(Host Config)는 ‘어떻게 바꿀지’를 구현한다

6. 이 구조를 이해하면 무엇이 달라질까?

✨ react-three-fiber의 설계가 보인다.

  • 씬의 구조는 React 트리가 관리하고
  • 매 프레임 변하는 값은 Reconciler 밖에서 처리하며
  • Three.js Scene Graph는 React 상태의 결과물이다