리덕스 dispatch와 render의 관계

신호승·2021년 1월 12일
2
post-thumbnail

피드백 환영합니다

One dispatch, one virtual DOM render

  • (dispatch가 store의 상태 변경을 유발하였을 경우) 리덕스는 모든 dispatch에 대해 모든 subscriber를 업데이트함
  • 상태를 각자 다른 reducer로 분리하는것과는 상관없음
  • e.g. 만약 store의 A field가 바뀌어도, B field를 구독하고 있는 컴포넌트에게도 기본적으로 noti가 가해짐
  • 하나의 리덕스 앱은 결과적으로 하나의 root reducer function만을 가지기 때문임

Redux app really only has one reducer function: the "root reducer" function that you will pass to createStore later on. That one root reducer function is responsible for handling all of the actions that are dispatched, and calculating what the entire new state result should be every time.
source: https://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers#writing-reducers

  • 또한, 여러 번의 dispatch가 실행될 경우 virtual dom render도 그 횟수만큼 실행
  • 다만, dispatch 하였을 때 store를 구독하고 있는 컴포넌트가 하나도 없다면 virtual DOM render 또한 일어나지 않음

Connect, useSelector의 차이점

  • 모든 컴포넌트에게 noti를 하는 것은 맞으나, 내부적으로 connect를 사용하여 props를 전달하였을 경우에는 shallow compare를 통해 그 값이 바뀌었을 때만 re-render를 유발함
  • useSelector 훅을 사용하였을 경우에는 이전 값과 비교하지만, === operator로 reference 비교를 하기 때문에 주의해야 할 사항이 있음. 아래 참조

useSelector로 object가 아닌 값을 return 하는 경우

import React from 'react'
import { useSelector } from 'react-redux'

export const CounterComponent = () => {
  const counter = useSelector(state => state.counter)
  return <div>{counter}</div>
}
  • 이 경우에 counter는 number 값이며, state.counter의 값이 바뀌지 않았다고 하면 === operator로 비교했을 때 true 일 것이므로, 리렌더링 되지 않음.

useSelector로 object를 return 하는 경우

import React from 'react'
import { useSelector } from 'react-redux'

export const CounterComponent = () => {
  const {counter} = useSelector(state => ({counter : state.counter}))
  return <div>{counter}</div>
}
  • 이 경우에 useSelector의 인자로 들어간 함수가 반환하는 값은 항상 새로운 object이며, 이 경우 === operator로 비교했을 때 false 일 것이므로 state.counter가 변경되지 않았다고 할지라도 리렌더링을 유발함

One dispatch do not induce one UI render

  • 최종적으로 여러번의 dispatch가 끝난 다음, state가 마지막 상태로 동기화가 되면 그때 batched_update를 통해 한꺼번에 fiber에 변화를 반영하여 UI 렌더가 일어남

dispatch 최적화에 대해

  • 한 dispatch에 여러 액션이 동시에 수행되도록 batching 하기
  • 다만, 간단한 CRUD 앱의 경우 굳이 이런 공수를 들여 최적화할 필요는 없음
  • 실시간으로 많은 양의 데이터를 주고받는 앱의 경우에 필요함
  • e.g. 코인 거래소(실시간 호가 렌더), 채팅앱(실시간 동시다발적 채팅)

reference

https://react-redux.js.org/next/api/hooks#performance
idiomatic-redux-thoughts-on-thunks-sagas-abstraction-and-reusability
React batched update 그리고 react-redux
dispatch & actual render relations

profile
Front-End developer

0개의 댓글