항해99_7기/4주차 React 숙련 주차

[항해99] 리액트 기초반 - 5주차(5-1~5-5 , 5-9~5-10)

code10 2022. 5. 27. 23:30

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

 

5-10. 끝