17일차

태권·2022년 8월 17일
0

개발일지

목록 보기
6/19
post-custom-banner

리덕스를 어느정도 쓸수 있게 되었다 아직 파이어베이스를 쓰는것은 조금 헷갈린다

const docRef = await addDoc(collection(db, "ranking"), {
            user_name: user[user_num - 1].user_name,
            score: scores,
            text: textref.current.value,
          });

간단하게 FB에서 값을 넣는 식이다. 다른것과 비교를 해보자 CRUD 이 4가지 방식을 아래 적고 비교하고 머가 다르고 어떻게 쓸지를 생각해보자

미들웨어
redux-thunk는 객체 대신 함수를 생성하는 액션 생성함수를 작성할 수 있게 해준다.
이는 리덕스는 기본적으로 액션객체를 디스패치한다.
이러면 함수를 생성하면 특정 액션이 발생하기 전에 조건을 주거나, 어떤 행동을 사전에 처리할 수 있다.

어느 컴포넌트에서 onclick에 디스패치를 달면 리덕스 파일 있는데로 보내져서 액션함수가 실행이 되고 액션에 디스패치하면서 가져온 값을 액션이 액션 타입과 값을 가지게 되고
이를 리듀서에서 쓸수 있게 되는것이다.

일단 FB에서 리스트르 가져와서 로드를 하고 값을 변경 하고 그러면 디스패치하면서 먼저 FB에 먼저 값을 변경하고 다하고 나서 그 객체를 가지고 와서 액션 함수를 돌려준다. 그리고 그값을 리덕스에 저장하고 렌더링도 하기 위해서 리듀서를 사용해준다.

import { createStore, combineReducers, applyMiddleware } 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

//리듀서가 있는 파일

// 액션 타입 을 지정해주자
const LOAD = "bucket/LOAD";
...
// 액션 생성 함수를 만들자
export function loadBucket(bucket_list){
  return {type: LOAD, bucket_list};
}

디스패치하면 액션 함수가 생성되기전에 미들웨어에서 먼저 처리를 할꺼다.


import {
  collection,doc,getDoc,getDocs,addDoc,updateDoc,deleteDoc,} from "firebase/firestore";

import {db} from "../../firebase";

// 파이어베이스랑 통신하는 부분 이제 이 함수를 onclick할떄 디스패치(FB함수(값))형태로 만들면 된다.
export const loadBucketFB = () => {
  return async function (dispatch) { 
    // 데이터를 가져와요! dispatch는 이함수안에서 쓸려고 넣어주었다
    const bucket_data = await getDocs(collection(db, "bucket"));
    // getDocs를 써서 콜력션 db의 어떤 거를 가져올지 정해준다
    let bucket_list  = [];

    // 하나씩 우리가 쓸 수 있는 배열 데이터로 만들어줍시다! 참조값이기 떄문에 배열로 만들어줌
    bucket_data.forEach((b) => {
      // 콘솔로 확인해요!
      console.log(b.id, b.data());
      bucket_list.push({ id: b.id, ...b.data() });
    });
    dispatch(loadBucket(bucket_list));
    //원래의 액션 함수를 불러준고 값을 넣어준다
  }
}

리듀서에서는 그냥 list에 bucket_list를 넣어주만 하면 된다.
불러오기는 파일 하나에서 완성하지만 나머지는 원래 컴포넌트 파일에서 디스패치해주는 곳에서 원래 액션함수가 아니라 FB 함수로 대치해주면 된다.

// App.js
React.useEffect( () => {
    dispatch(loadBucketFB());
  }, []);

비동기작업이나 돔에 따로올라가지 않고 나중에 런더링될수있게 쓰는것? 보통 외부데이터 가져올때 useEffect안에 넣어준다.
그리고 만약 map같은걸 써서 데이터를 넣는데 오류가 뜨면 삼항연산자로 데이터가 있을때 없을때로 나눠보자 초기 값이 없는데 나중에 값을 불러오기때문에 오류가 날수도 있다.

create

//bucket.js

// App.js
const addBucketList = () => {
dispatch(addBucketFB({ text: text.current.value, completed: false }));
};
// 이렇게 FB 함수에 값을 먼저 디스패치 하고 리덕스 파일 안에서 다시 원래 액션함수로 디스패치를 해준다.


// 파이어베이스랑 통신하는 부분
export const addBucketFB = (bucket) => {
  return async function (dispatch) {
		// 파이어스토어에 추가하기를 기다려요!
    const docRef = await addDoc(collection(db, "bucket"), bucket);
		// 추가한 데이터 중 id를 가져와서 bucket_data를 만들어줬어요!
        //const _bucket = await getdoc(docRef)  docRef는 참조값으로 getdoc으로 객체로 만들고 다시 불러오는것이기때문에 await를 해줘야한다. 아래줄은 원래 bucket에 값을 담고 그걸 id만 붙이면 되니 아래처럼 하자
    const bucket_data = { id: docRef.id, ...bucket };
		// 그럼 이제 액션을 일으키자! (수정해달라고 요청하자!)
    dispatch(createBucket(bucket_data));
  }
}
//이제 가져온값은 객체 하나니 리듀서에서 원래 리스트에 붙이는 것처럼 만들면 된다.

update

//bucket.js


export const updateBucketFB = (bucket_id) => {
  return async function (dispatch, getState) {
		// 수정할 도큐먼트를 가져오고, getState로 기본값을 가져올수 있다.
    const docRef = doc(db, "bucket", bucket_id);
		// 수정합시다! doc로 하나를 고를 수 있다 
    await updateDoc(docRef, { completed: true });
		// getState()를 사용해서 스토어의 데이터를 가져올 수 있어요.//딱 여기까지가 값 없데이트 하는거 이후는 리덕스에 데이터 넣기 안그러면 새로고침해야 렌더링이 될꺼니까
    console.log(getState().bucket);
    // bucket list 데이터를 가져와요.
    const _bucket_list = getState().bucket.list;
		// findIndex로 몇 번째에 있는 지 찾기! 
    const bucket_index = _bucket_list.findIndex((b) => {
			// updateBucketFB의 파라미터로 넘겨받은 아이디와 
			// 아이디가 독같은 요소는 몇 번째에 있는 지 찾아봐요!
      return b.id === bucket_id;
    })

    dispatch(updateBucket(bucket_index));
    // 키값이 인덱스가 아니라 id 이면 리듀서에서 굳이 인덱스 값말고 id 값으로 비교하면 되니까 findIndex 필요없이 받아온 id 값을 map 돌려서 id값이 같은거를 true로 바꾸면 되지 않나싶다 어차피 리듀서에서 인덱스 값가지고 다시 트로로 바꾸는거 할테니까
  }; 
};

Delete

//bucket.js

// 파이어베이스랑 통신하는 부분
export const deleteBucketFB = (bucket_id) => {
  return async function (dispatch, getState) {
    if(!bucket_id){
      window.alert("아이디가 없네요!");
      return;
      // 이부분은 만약 파라미터 값이 없는 경우를 대비해 만들았고 update 부분에도 쓰면된다 아래는 업데이트랑 같다.
    }
    const docRef = doc(db, "bucket", bucket_id);
    await deleteDoc(docRef);

     const _bucket_list = getState().bucket.list;
     const bucket_index = _bucket_list.findIndex((b) => {
       return b.id === bucket_id;
     });

     dispatch(deleteBucket(bucket_index));
  }
}
profile
2022.08 개발자 시작
post-custom-banner

0개의 댓글