[항해99] 리액트 기초반 - 5주차(5-1~5-5 , 5-9~5-10)
5-1. 리덕스에서 FireStore 데이터 가지고 놀기 (1)
미들웨어가 뭐냐구요? 리덕스 데이터를 수정할 때 [액션이 디스패치 되고 → 리듀서에서 처리] 하던 과정 기억하시죠?
미들웨어는 이 과정 사이에 미리 사전 작업을 할 수 있도록 하는 중간 다리 같은 것.
즉! [액션이 일어나고 → 미들웨어가 할 일 하기 → 리듀서에서 처리] 이 순서로 처리.
yarn add redux-thunk
redux-thunk는 뭐하는 미들웨어일까?
redux-thunk는 객체 대신 함수를 생성하는 액션 생성함수를 작성할 수 있게 해줍니다!
리덕스는 기본적으로는 액션 객체를 디스패치합니다! → 즉, 함수를 생성하면 특정 액션이 발생하기 전에 조건을 주거나, 어떤 행동을 사전에 처리할 수 있겠죠!!
<configStore.js에 미들웨어를 추가>
import { createStore, combineReducers, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import bucket from "./modules/bucket";
export const history = createBrowserHistory();
const middlewares = [thunk];
const enhancer = applyMiddleware(...middlewares);
const rootReducer = combineReducers({ bucket });
const store = createStore(rootReducer, enhancer);
export default store;
5-2. 리덕스에서 FireStore 데이터 가지고 놀기 (2)
firestore 적용하기
(1) load할 때 데이터를 가지고 와보자!
> 일단은 액션부터!
> 파이어베이스랑 통신하는 함수 만들고,
> 리듀서를 고쳐요!
> 그 후에는요? 불러다 쓰면 되겠죠!
(2) create에 firestore 적용
(3) update에 firestore 적용
(4) delete에 firestore 적용
5-3. 머테리얼 UI 사용하기
머테리얼 UI 설치하기
공식 문서(https://material-ui.com/)
<강의 촬영 시점과 달라진 코드.. 사이트에서 확인 잘해서 설치해야 한다..>
yarn add @mui/material @emotion/react @emotion/styled
import 해오는 코드도 강의자료와 다르니 유의..
import Button from '@mui/material/Button';
5-4. 페이지 의도적으로 가리기
페이지를 왜 가려야 하나?
<aside> 👉 redux에 넣어둔 데이터 때문에 자꾸만 가짜 데이터 3개가 먼저 보이죠! 파이어스토어의 데이터만 제대로 보여주고 싶을 때, 어떻게 하면 좋을까요? 😎 → 그렇죠! 페이지를 가려버리는 거예요. 언제까지? 파이어스토어에서 데이터를 가져올 때까지!
</aside>
수정이나 추가하기 버튼을 눌렀을 때, 여러번 API를 호출하는 현상을 방지하기 위해
1) 로딩 스피너 컴포넌트 만들기(Sppiner.js)
2) firestore 데이터 가져오기 전엔 페이지 진입을 막자!
-initialState에 is_loaded라는 변수를 추가하고 firestore에서 데이터를 받아오면 갱신.
//bucket.js
...
const initialState = {
is_loaded: false,
list: [],
};
...
case "bucket/LOAD": {
return { list: action.bucket, is_loaded: true };
}
3) 변수를 App.js에서 보고, 조건부 랜더링
import Spinner from "./Spinner";
const is_loaded = useSelector(state => state.bucket.is_loaded);
{!is_loaded && <Spinner />}
...
import { useDispatch, useSelector } from "react-redux";
...
import Spinner from "./Spinner";
...
function App() {
const text = React.useRef(null);
const dispatch = useDispatch();
const is_loaded = useSelector(state => state.bucket.is_loaded);
React.useEffect( () => {
dispatch(loadBucketFB());
}, []);
const addBucketList = () => {
dispatch(addBucketFB({ text: text.current.value, completed: false }));
};
return (
<div className="App">
...
{/* 인풋박스와 추가하기 버튼을 넣어줬어요. */}
<Input>
<input type="text" ref={text} />
<button onClick={addBucketList}>추가하기</button>
</Input>
{!is_loaded && <Spinner />}
</div>
);
}
...
export default App;
5-5. Quiz_버킷리스트 생성 시 스피너 띄우기
추가하기 버튼을 누르면 → 로딩 스피너를 띄우고 → 추가가 끝나면 → 페이지를 보여줍시다!
힌트: is_loaded를 false로 바꿔주면 스피너가 뜨겠죠? is_loaded를 바꿔주는 액션을 만들고, [추가하기]를 누르면 액션을 디스패치 해봅시다. 그리고 addBucketFB()에서 추가가 끝나면 다시 is_loaded를 false로 바꿔줍시다. 🙂
5-9. Firebase로 배포하기
firebase 호스팅하기
- 대시보드에서 호스팅 신청하기
- 우리 프로젝트에 cli 설치
yarn add global firebase-tools
- firebase에 로그인하고 init 실행하기
#웹브라우저가 열리고 내 구글 계정을 물어볼거예요. 로그인해줍니다.
yarn firebase login
#로그인 후 init!
yarn firebase init
호스팅을 선택해줍니다(방향키로 이동해요)
-firestore, hosting 선택. / public 말고 build 입력
firebase.json에서 확인.
{
"hosting": {
"public": "build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
빌드한 결과물 올리기
yarn firebase deploy