일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Uncaught Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider>
- express session
- 라우터와 미들웨어
- buffer.from
- express실행
- javascript기초
- nodejs파일업로드
- express.static
- next 매개변수
- mysql wsl
- 비동기파일업로드
- useContext
- FormData()
- 블록 만들기
- ws 라이브러리
- cookie-parser 만들어보기
- express router
- node.js path
- 시퀄라이즈 기본설정
- css기초
- JWT 하드코딩
- 아이디 중복체크기능
- 세션으로 로그인 구현
- JWT 만들어보기
- 라우터미들웨어 분리
- JWT 로그인 기능 구현
- 라우터 분리
- useEffect clean up
- OAuth 카카오
- 라우트 매개변수
- Today
- Total
즐코
redux-middleware (redux-thunk) 본문
action이 reducer에게 dispatch되기 전 추가적인 작업을 할 수 있게 해주는 게 미들웨어
쉽게 말하자면, action이 reducer-store에 가기 전 중간에 실행하는 함수들의 모음을 미들웨어라고 본다.
리액트 앱에서 back 서버에 axios요청을 날리거나 할 때 리덕스 미들웨어를 사용해서 처리하곤 한다.
액션 -> 미들웨어1 -> next -> 미들웨어2 -> next -> 리듀서 -> 스토어
미들웨어 템플릿은 아래와 같이 두 개의 함수를 연달아서 리턴해주는 고차함수이다.
function middleware(store) {
return function (next) {
return function (action) {
// 작업~~
}
}
}
두 개의 익명함수를 리턴하기때문에 대부분 아래처럼 화살표 함수로 나타낸다.
const middleware = (store) => (next) => (action) => {
// 작업~~
}
1. store : 리덕스 스토어의 인스턴스 / 대표적인 내장함수는 아래와 같다.
- store.getState() : 상태에 조회,접근하게 해주는 내장함수
- store.dispatch(action) : 액션을 리듀서에게 전달해서 상태를 바꿔주는 내장함수
- store.subscribe(함수이름) : 상태가 바뀌고 나서 인자로 등록해둔 함수가 실행되게 해주는 내장함수
함수를 등록하고 나서 (subscribe), 그 이후에 상태변경을 하면(dispatch), log 함수가 실행된다.
상태를 조회해보면 상태 또한 업뎃되있음. 즉, 상태변경 전에 뭔가를 실행하고 싶다면 쓰는 함수다.
// log 함수 선언
const log = () => {
console.log('hello world')
console.log(store.getState())
}
store.subscribe(log) // log 함수 등록
store.dispatch({ type: GET_COFFEE }) // 상태 변경
/*
결과
hello world // subscribe 등록해둔 log 함수 실행
{ name: 'yjlee', coffee: 2 } // 현재 상태 조회(원래 1이였는데 2로 상태변경됨)
*/
2. next : action을 다음 미들웨어에게 전달해주는 함수
- express에서 next를 써서 미들웨어를 연결해주었는데, 이것도 비슷하게 다음으로 넘어갈지말지 결정해주는 메소드이다.
- 다음 미들웨어가 없다면 리듀서에게 액션을 전달한다.
- next를 써주지 않으면 액션이 무시되어서 리듀서에게 전달되지 x
3. action : 현재 미들웨어에서 처리하는 중인 액션 객체임
액션 -> 미들웨어1 -> next -> 미들웨어2 -> next -> 리듀서 -> 스토어
-> store.dispatch : 다른 액션 추가 발생 -> 액션 -> 미들웨어1-1 -> next -> 미들웨어1-2 -> ...
이 때 store가 가지고 있는 내장함수 dispatch, getState는 상태변경 및 상태를 조회하면서 많이 쓰기 때문에,
아래처럼 store 대신 {dispatch, getState}를 넣어준다.
const middleware = ({dispatch,getState}) => (next) => (action) => {
//
}
redux-thunk ?
- 코드가 짧아서 설치하지않고 직접 써봄
- action 객체 대신 함수를 생성하는 액션 생성 함수를 작성하게 해줌
저번에 배운 액션 생성함수는 비동기 처리가 불가능했음
(특정 액션이 몇초뒤에 실행되게 하거나 상태에 따라서 액션이 무시되게 하려는 등..)
const add_cmmt = (payload) => ({ type:'ADD_CMMT', payload })
보통은 action값으로 객체를 전달해주지만, 함수를 전달해줄 경우 이에 따른 미들웨어를 만들 수도 있겠다.
action값이 함수일 경우를 예를 들어보면, 아래 loginAPI 같은거라고 보면 된다.
axios로 백서버에 로그인 요청을 한다면 위와 같은 loginAPI 함수가 action으로 들어갈 수 있는데,
const loginAPI = () => async dispatch => {
dispatch( {type : '로그인 요청옴'} ) // 여기서 로딩중 이런 걸 띄워줘도 됨
const body = { id: 'yjlee', pw: '1234' }
try {
const result = await axios.post('http://localhost:4000/api/user/login', body)
// result.data 성공
dispatch({ type: '로그인성공' }, payload: {로그인 정보})
} catch (err) {
dispatch({ type: '로그인실패' }, payload : false )
}
}
store.dispatch(loginAPI())
그러면 아래 미들웨어 thunk에서 이 action을 받고 action type이 함수면, 이 함수를 호출, 실행시킬 수 있다는 얘기일거다.
그렇기 때문에 이 action함수의 인자로 dispatch를 넣어주면, 그 dispatch를 이용해서, 조건을 나눠서 dispatch를 날려줄 수 있다.
가령 위의 login api의 경우, 로그인 성공/실패에 나눠서 다른 dispatch를 날리는데, 이땐 드디어 action이 객체로 날라가게 된다.
그러면, 이제 action이 함수가 아닌 객체이므로 next(action) 이 실행되고 다음 미들웨어나 미들웨어가 없다면, reducer에게 간다.
const thunk = ({ dispatch, getState }) => (next) => (action) => (
typeof action === 'function' ?
action(dispatch) : next(action)
)
const middleware = [thunk]
const enhancer = compose(applyMiddleware(...middleware))
const store = createStore(rootReducer, enhancer)
미들웨어 스토어에 적용하기
- applyMiddleware : 여러 미들웨어들을 스토어에 적용 시켜줌
- compose : 미들웨어 여러 개 넣어줄 때 쓰는 내장 함수라고 생각하자.
리액트에선 컴포넌트 안에서 dispatch를 사용해야했다. (useDispatch를 import해와서 컴포넌트 안에서 사용했다)
그런데 이렇게 할 경우엔 함수 선언 시에 dispatch를 넣으니까 로직에 대한 코드를 다른 파일에서 작성이 가능하다
출처 : https://react.vlpt.us/redux-middleware/02-make-middleware.html
'React' 카테고리의 다른 글
useRef 복습 - 변수관리 (state와는 다르다!) (0) | 2022.05.11 |
---|---|
useEffect 복습 (0) | 2022.05.10 |
React-router / redux 상태관리 라이브러리 맛보기 (0) | 2022.05.03 |
props와 state (0) | 2022.04.13 |
리액트 기초오브기초 (0) | 2022.04.13 |