redux-thunk란?
- Firestore에서 데이터를 가져올 때 비동기 통신을 함
- 리덕스에서 비동기 통신을 할 때 미들웨어가 필요함
- 일반 액션 생성 함수는 객체를 반환하는데 redux-thunk는 객체 대신 함수를 생성하는 액션 생성함수를 작성할 수 있게 해줌
- 함수를 생성하면 특정 액션이 발생하기 전에 조건을 주거나 행동을 할 수 있음
미들웨어
- 리덕스 데이터를 수정할 때 액션 디스패치 → 리듀서에서 처리
- 미들웨어가 있으면 액션 디스패치 → 미들웨어가 할일 → 리듀서에서 처리
설치하기
yarn add redux-thunk
configStore.js
- redux-thunk 적용 전 configStore.js
import {createStore, combineReducers} from 'redux';
import bucket from './modules/bucket';
import {createBrowserHistory} from 'history';
export const history = createBrowserHistory();
const rootReducer = combineReducers({bucket});
const store = createStore(rootReducer);
export default store;
- redux-thunk 적용 후 ⬇
import {createStore, combineReducers, applyMiddleware, compose} from 'redux';
import thunk from 'redux-thunk';
import bucket from './modules/bucket';
import {createBrowserHistory} from 'history';
export const history = createBrowserHistory();
const middlewares = [thunk];
const enhancer = applyMiddleware(...middlewares);
const rootReducer = combineReducers({bucket});
const store = createStore(rootReducer, enhancer);
export default store;
Load하기
bucket.js 수정
- Firebase랑 통신하는 함수 생성
const bucket_db = firestore.collection('bucket');
export const loadBucketFB = () => {
return function (dispatch) {
bucket_db.get().then((docs) => {
let bucket_data = [];
docs.forEach((doc) => {
if(doc.exists){
bucket_data = [...bucket_data, {id: doc.id, ...doc.data()}];
}
});
dispatch(loadBucket(bucket_data));
});
};
};
- 리듀서 수정
case 'bucket/LOAD': {
if (action.bucket.length > 0) {
return {list: action.bucket};
}
return state;
}
App.js 수정
const mapDispatchToProps = (dispatch) => ({
load: () => {
dispatch(loadBucketFB());
},
create: (new_item) => {
dispatch(createBucket(new_item));
}
});
Create 하기
bucket.js 수정
- Firebase와 통신하는 함수 생성
export const addBucketFB = (bucket) => {
return function (dispatch) {
let bucket_data = {text: bucket, completed: false};
bucket_db
.add(bucket_data)
.then((docRef) => {
bucket_data = {...bucket_data, id: docRef.id};
dispatch(createBucket(bucket_data));
});
.catch((err) => {
window.alert('오류 발생');
});
};
};
- 리듀서 수정
case 'bucket/CREATE': {
const new_bucket_list = [
...state.list,
action.bucket,
];
return {list: new_bucket_list};
}
App.js
const mapDispatchToProps = (dispatch) => ({
load: () => {
dispatch(loadBucketFB());
},
create: (new_item) => {
dispatch(addBucketFB(new_item));
}
});
Update 하기
bucket.js
export const updateBucketFB = (bucket) => {
return function (dispatch, getState) {
const _bucket_data = getState().bucket.list[bucket];
if (!_bucket_data.id) {
return;
}
let bucket_data = {..._bucket_data, completed: true};
bucket_db
.doc(bucket_data.id)
.update(bucket_data)
.then((res) => {
dispatch(updateBucket(bucket));
})
.catch((err) => {
});
};
};
Detail.js
<button onClick={() => {
dispatch(updateBucketFB(bucket_index));
props.history.goBack();
}}>완료하기</button>
Delete 하기
bucket.js
export const deleteBucketFB = (bucket) => {
return function (dispatch, getState) {
const _bucket_data = getState().bucket.list[bucket];
if (!_bucket_data.id) {
return;
}
bucket_db
.doc(_bucket_data.id)
.delete()
.then((res) => {
dispatch(deleteBucket(bucket));
})
.catch((err) => {
});
};
};
Detail.js
<button onClick={() => {
dispatch(deleteBucketFB(bucket_index));
props.history.goBack();
}}>삭제하기</button>
'[스파르타코딩클럽] > 프론트엔드의 꽃, 리액트' 카테고리의 다른 글
프론트엔드의 꽃, 리액트 5주차 정리 (AWS S3 버킷, Route 53 이용해서 정적 웹 호스팅, Firebase로 배포하기) (0) | 2021.09.07 |
---|---|
프론트엔드의 꽃, 리액트 5주차 정리 (Material UI, Firestore 데이터 로드 여부로 조건부 렌더링) (0) | 2021.09.07 |
프론트엔드의 꽃, 리액트 4주차 정리 (Firebase, 리액트에 Firestore 연동하기) (0) | 2021.08.19 |
프론트엔드의 꽃, 리액트 4주차 정리 (애니메이션 keyframes) (0) | 2021.08.19 |
프론트엔드의 꽃, 리액트 3주차 정리 (리덕스, react-redux) (0) | 2021.08.06 |