useEffect에서 async function을 사용함으로써
useEffect의 return 값으로 Promise를 넘기고
이는 useEffect의 콜백인 cleanup 함수를 올바르게 사용할 수 없게 만든다.
Thinking in Thunks
What is a "Thunk"?
The Redux core (ie, createStore) 은 완벽하게 동기적이다.
따라서 비동기적 작동은 store 외부에서 발생해야 한다.
그러나 만약 비동기 로직을 store와 연동해서 작동하고 싶을 때 => Redux middleware
middleware는 store를 확장하여 다음의 기능을 제공
action이 dispatch 되었을 때 extra logic을 수행 (logging)
Pause, modify, delay, replace, halt dispatched actions
dispatch and getState를 사용한 코드 작성
dispatch에게 plain action object외의 값들을 어떻게 사용할 것인지 가리치는 역할을 한다. (intercepting하여 조작 후 real action object를
dispatching하는 방법으로)
Redux store에 middleware 더함으로 function을 바로 store.dispath()에 pass
the thunk middleware는 그 함수를 보고, 그것이 real store에 도달하지 못하도록 막고,
함수를 호출하고 그리고 dispatch와 getState를 인자로 넘김
function exampleThunkFunction(dispatch, getState) {
// do something useful with dispatching or the store state here
}
// normally an error, but okay if the thunk middleware is added
store.dispatch(exampleThunkFunction)
////////////////using thunk action creator/////////////////
function exampleThunk() {
return function exampleThunkFunction(dispatch, getState) {
// do something useful with dispatching or the store state here
}
}
// normally an error, but okay if the thunk middleware is added
store.dispatch(exampleThunk())
Why Use Thunks?
store와 interact하는 재사용가능한 코드를 store에 직접 reference 없이 작성 가능
component 밖에서 더 복잡한 로직을 가능하게 한다
component는 어디서 action과 async logic을 kick off 하는지는 중요하지 않다.
단지 dispatch 할 뿐
promise 값을 return 가능 하여 컴포넌트내의 로직이 다른 것이 끝날때가지 기다리게 한다.
redux-saga, redux-observable은 좋은 framework이지만 기능을 다 사용하기 어려워
디폴트로 사용하기 좋다.
Writing Thunks in Redux Toolki
redux toolkit의 configureStore에서 자동으로 등록
RTK thunk function을 쓰는 어떤 syntax나 function 제공하지 않는다.
일반적으로 관련 action 파일이나 slice 파일 안에 위치한다.
위 코드의 try catch 문은 getRepoDetails와 dispatch(getRepoDetailsSuccess(repoDetails))의 에러를
모두 dispatch(getRepoDetailsFailed(err.toString()))로 처리하는 문제가 있어 다음과 같은 해결책을 생각해 볼 수 있다.
chapter 에서 다룰 내용
완성 코드 https://github.com/reduxjs/rtk-github-issues-example
예제 application
링크 : https://codesandbox.io/s/rtk-github-issues-example-01-plain-react-8jf6d?from-embed 프로젝트 구조 :
Redux Store Setting
🔗Add Redux Toolkit and React-Redux packages
Creating the Root Reducer
🔗Add store and root reducer with reducer HMR
Rootstate
ReturnType 을 이용한다.
※ 다른 방법은 Using configureStore with TypeScript 참고
Provider
Main App Display
어떤 state를 redux에 둘 것 인가
https://redux.js.org/faq/organizing-state#do-i-have-to-put-all-my-state-into-redux-should-i-ever-use-reacts-setstate
Initial State Slices
redux에 두기로한 state를 대상으로 types와 initial state을 작성한다. 여기서 부터 이들을 업데이트할 reducer를 정의 할 수 있다. 🔗Add initial state slice for UI display
State Contents Type Declarations
후에 action type이나 entire state에서 재사용을 위해 state type Declaration이 필요
Declaring Types for Slice State and Actions
createSlice 두 개의 sources 로 부터 타입을 추론
Converting the Issues Display
🔗Convert main issues display control to Redux
Converting the Issues List Page
useEffect에서 async function을 사용함으로써 useEffect의 return 값으로 Promise를 넘기고 이는 useEffect의 콜백인 cleanup 함수를 올바르게 사용할 수 없게 만든다.
Thinking in Thunks
What is a "Thunk"?
The Redux core (ie, createStore) 은 완벽하게 동기적이다. 따라서 비동기적 작동은 store 외부에서 발생해야 한다. 그러나 만약 비동기 로직을 store와 연동해서 작동하고 싶을 때 => Redux middleware
middleware는 store를 확장하여 다음의 기능을 제공
Redux store에 middleware 더함으로 function을 바로 store.dispath()에 pass the thunk middleware는 그 함수를 보고, 그것이 real store에 도달하지 못하도록 막고, 함수를 호출하고 그리고 dispatch와 getState를 인자로 넘김
Why Use Thunks?
redux-saga, redux-observable은 좋은 framework이지만 기능을 다 사용하기 어려워 디폴트로 사용하기 좋다.
Writing Thunks in Redux Toolki
redux toolkit의 configureStore에서 자동으로 등록
RTK thunk function을 쓰는 어떤 syntax나 function 제공하지 않는다. 일반적으로 관련 action 파일이나 slice 파일 안에 위치한다.
Logic for Fetching Github Repo Details
Adding a Reusable Thunk Function Type
🔗Add AppThunk type
Adding the Repo Details Slice
🔗Add a slice for storing repo details
Async Error Handling Logic in Thunks
위 코드의 try catch 문은 getRepoDetails와 dispatch(getRepoDetailsSuccess(repoDetails))의 에러를 모두 dispatch(getRepoDetailsFailed(err.toString()))로 처리하는 문제가 있어 다음과 같은 해결책을 생각해 볼 수 있다.
1) promise chain코드로 변경 후, success와 fail 콜백을 사용하도록
2) 코드의 위치 변경
Converting the Issue Details Page
Fetching the Issue Comments
connect api와는 다르게 useSelector는 reference동일성을 기본으로 한다. 그래서 action이 dispatch 될 때마다 새로운 object를 반환하고 이는 컴포넌트가 rerender 되도록 한다.
이를 위한 해결방안은