06. Redux와 TDD - 1

surra77·2024년 2월 29일
0

106. 리덕스란?

Redux

리덕스는 자바스크립트 애플리케이션을 위한 상태 관리 라이브러리

Redux 데이터 Flow

redux의 데이터 흐름은 strict unidirectional data flow 으로 한 방향으로 흘러감

Action -> Reducer -> Redux Store -> React Component -> Action

Action

Action은 간단한 자바스크립트 객체. 여기에는 우리가 수행하는 작업의 유형을 지정하는 'type' 속성이 있으며 선택적으로 redux 저장소에 일부 데이터를 보내는데 사용되는 'payload' 속성을 가질 수도 있음

Reducer

reducer는 애플리케이션 상태의 변경 사항을 결정하고 업데이트된 상태를 반환하는 함수. 인수로 조치를 취하고 store 내부의 상태를 업데이트함

이전 State와 action object를 받은 후에 next State를 return 함

(previousSate, action) => nextSate

reducer는 순수 함수!
하지말아야 될 것들

  • 매개변수 변경
  • API 호출이나 라우팅 변경과 같은 side effects
  • non-pure 함수 호출 ex) Date.now(), Math.random()

Store

객체 저장소 Store는 애플리케이션의 전체 상태 트리를 보유. 내부 상태를 변경하는 유일한 방법은 해당 상태에 대한 Action을 전달하는 것. Redux Store는 클래스가 아님. 몇 가지 메소드가 있는 객체일 뿐!

subscribe()
change listener를 추가. 작업이 전달될 때마다 호출되며 상태 트리의 일부가 잠재적으로 변경되면 getState()를 호출하여 콜백 내부의 현재 상태 트리를 읽음

예시)

const store = createStore(counter);

const render = () =>
  root.render(
    <React.StrictMode>
      <App
        value={store.getState()}
        onIncrement={() => store.dispatch({ type: "INCREMENT" })}
        onDecrement={() => store.dispatch({ type: "DECREMENT" })}
      />
    </React.StrictMode>
  );

render();
store.subscribe(render);

109. Redux Provider

Provider란?

<Provider> 구성 요소는 Redux Store 저장소에 엑세스해야 하는 모든 중첩 구성 요소에서 Redux Store 저장소를 사용할 수 있도록 해줌

Redux의 모든 React 구성 요소는 저장소에 연결할 수 있으므로 대부분의 응용 프로그램은 전체 앱의 구성 요소가 트리 내부에 있는 최상위 수준에서 <Provider>를 렌더링 함
그런 다음 Hooks 및 연결 API는 React의 컨텍스트 메커니즘을 통해 제공된 저장소 인스턴스에 엑세스 할 수 있음


110. useSelector & useDispatch

provider로 둘러 쌓인 컴포넌트에서 store 접근

리액트에 Hooks가 있듯이 리덕스에도 Hooks가 있는데 그게 바로 useSelector와 useDispatch
이 두 개를 이용해서 provider로 둘러 쌓인 컴포넌트에서 store에 접근 가능

useSelector

useSelector Hooks를 이용해서 스토어의 값을 가져올 수 있음

const counter = useSelector((state) => state.counter)

useDispatch

store에 있는 dispatch 함수에 접근하는 Hooks


111. 리덕스 미들웨어

리덕스 미들웨어란?

Redux 미들웨어는 액션을 dispatch 전달하고 리듀서에 도달하는 순간 사전에 지정된 작업을 실행할 수 있게 해주는 중간자

로깅, 출돌 보고, 비동기 API와 통신, 라우팅 등을 위해 Redux 미들웨어를 사용


112. Redux Thunk

리덕스 Thunk란?

Redux Thunk도 리덕스 미들웨어이며, 리덕스를 사용하는 앱에서 비동기 작업을 할 때 많이 사용하는 방법

Thunk 뜻

"thunk"라는 단어는 "일부 지연된 작업을 수행하는 코드 조각"을 의미하는 프로그래밍 용어
지금 일부 로직을 실행하는 대신 나중에 작업을 수행하는데 사용할 수 있는 함수 본문이나 코드를 작성할 수 있음

결론

리덕스 thunk를 사용함으로써 액션 생성자가 그저 하나의 액션 객체를 생성할 뿐 아니라 그 내부 안에서 여러 가지 작업도 할 수 있게 만들어 줌


113. 리덕스 툴킷 (redux toolkit)

리덕스 툴킷

Redux 툴킷은 리덕스 로직을 작성하기 위한 공식 권장 접근 방식
Redux 코어를 둘러싸고 있으며 Redux 앱을 빌드하는데 필수적이라고 생각하는 패키지와 기능이 포함되어 있음
리덕스 툴킷은 제안된 모범 사례를 기반으로 대부분의 리덕스 작업을 단순화하고 일반적인 실수를 방지해주며 리덕스 애플리케이션을 더 쉽게 작성할 수 있도록 함


114. 리덕스 툴킷 APIs

Store 생성

기존 Redux는 createStore를 통해 Store 생성
리덕스 툴킷에서는 configureStore를 통해 생성

Action 생성

액션 타입 상수와 액션 생성자 함수 생성을 createAction 함수 하나로 처리

  • createAction은 type만 넣으면 자동으로 해당 type을 가진 action creator 함수를 생성함
  • 생성된 함수를 호출할 때 인수를 추가로 넣으면 이 값은 payload 프로퍼티 값으로 들어감

Reducer 생성

createReducer에서 Action을 처리하기 위해 케이스 리듀서를 정의하는 방법은 "빌더 콜백"(builder callback) 표기법과 "맵 객체"(map object) 표기법 두 가지가 있음. 둘 다 동일한 기능이지만 타입스크립트와의 호환성을 위해 "빌더 콜백" 표기법이 더 선호됨

builder callback 표기법

createReducer(initialState, builderCallback)

  • builder.addCase(actionCreator, reducer):
    액션 타입과 정확히 맵핑되는 케이스 리듀서를 추가하여 액션을 처리
    addMatcher 또는 addDefaultCase 보다 먼저 작성되어야 함

  • builder.addMatcher(matcher, reducer):
    새로 들어오는 모든 액션에 대해서 주어진 패턴과 일치하는지 확인하고 리듀서를 실행함

  • builder.addDefaultCase(reducer):
    다른 케이스 리듀서나 매처 리듀서가 실행되지 않았다면 실행되는 기본 케이스 리듀서

map object 표기법

createReducer(initialState, actionMap, actionMatchers, defaultCaseReducer)

  • initialSate: 리듀서를 처음 호출할 때 사용해야 하는 초기 상태 값

  • actionsMap: 액션 타입이 케이스 리듀서에 맵핑되어 있는 객체

  • actionMatchers:
    {matcher, reducer} 형식으로 정의된 배열
    케이스 리듀서가 일치하는지 여부에 관계없이 모든 일치하는 리듀서가 순서대로 실행됨

  • defaultCaseReducer:
    케이스 리듀서 및 매처 리듀서가 실행되지 않은 경우 실행되는 기본 케이스 리듀서

createSlice()

이 API는 Redux Logic을 작성하기 위한 표준 접근 방식
createSlice 내부에 createAction과 createReducer를 사용

createSlice 함수는 리듀서 함수의 초기 상태와 'slice 이름'을 받아 리듀서와 상태에 해당하는 액션 생성자와 액션 타입을 자동으로 생성하는 함수

extraReducers

extraReducers를 사용하면 createSlice가 생성한 action type 외에 다른 action type에 응답할 수 있음

extra Reducers로 지정된 케이스 리듀서는 '외부'액션을 참조하기 위한 것으로, 그들은 slice.actions에서 생성된 액션을 가지지 않음

createAsyncThunk

createAction의 비동기 버전

function createAsyncThunk(type, payloadCreator, options)
  • type: 비동기 요청의 생명주기를 나타내는 추가 Redux action type 상수를 생성하는데 사용되는 문자열
    예를들어 'users/requestStatus' type 인수는 다음과 같은 action type을 생성
    - pending: 'users/requestStatus/pending'
    - fulfilled: 'users/requestStatus/fulfilled'
    - rejected: 'users/requestStatus/rejected'

  • payloadCreator: Promise를 반환하는 콜백 함수
    - thunkAPI: 일반적으로 Redux thunk 함수에 전달되는 모든 매개변수와 추가 옵션을 포함하는 객체

    • dispatch: Redux 스토어 dispatch 메서드
    • getState: Redux 스토어 getState 메서드
    • extra: 설정시 thunk 미들웨어에 제공되는 '추가 인수'(사용 가능한 경우)
    • requestId: 이 요청 시퀀스를 식별하기 위해 자동으로 생성되는 고유 문자열 ID 값
    • signal: 앱 로직의 다른 부분이 이 요청을 취소가 필요한 것으로 표시했는지 확인하는데 사용할 수 있는 AbortController.signal 객체
    • rejectWithValue(value, [meta]): 정의된 페일드 및 메타와 함께 거부된 응답을 반환하기 위해 작업 생성자에서 반환(또는 throw)할 수 있는 유틸리티 함수
    • fulfilledWithValue(value, meta): fulfilledAction.meta에 추가할 수 있는 기능을 가지고 있는 동안 값으로 이행하기 위해 작업 생성자에서 반환할 수 있는 유틸리티 함수

cancellation

thunk 실행 중 취소하기

profile
개발자 준비생

0개의 댓글