[클론 코딩-트위터(React, Firebase)] '누이터' 핵심 기능 만들기 (CRUD- create read update delete, 파이어베이스 DB, 트윗)

안지수·2023년 5월 2일
0
post-custom-banner

: 파이어베이스 데이터베이스 배움 (사용법, 채팅 앱에서 쓰기 좋은 실시간 데이터 베이스, CRUD)

😀 트윗 등록 기능 만들기 (create)

: 트윗을 위한 만들고, 폼에서 전송한 데이터 파이어베이스 DB에 저장

1. 트윗을 위한 폼 만들기

  • Home.js

    -> 위와 같이 코드 수정

    -> 로그인 폼과 크게 다르지 않음! 위와 같은 화면이 나온다. 트윗 글자수는 maxLength 속성을 통해 제한시킴

2. 트윗을 위한 파이어베이스 데이터베이스 생성하기


-> firebase의 Database로 이동 후 데이터베이스 만들기

-> 테스트모드를 누르고 다음을 누르자. 테스트모드가 보안은 약하지만 개발이 편함. (누이터 완성되면 프로덕션 모드에서 시작으로 보안모드 설정 바꾸기)

-> 데이터베이스 사용할 준비 끝

3. 샘플 데이터 저장해 보기

: 파이어베이스에서 컬렉션을 수동적으로 등록
: 파이어베이스 DB는 NoSQL 기반
-> 컬렉션(폴더)과 문서(컬렉션 안에 포함되는 텍스트 문서)라는 체계 가지고 있음

-> 컬렉션 시작 누르고 id는 nweet


-> 이렇게 데이터베이스에 샘플 데이터가 저장 완료
-> 각 항목을 눌러 조회, 수정, 삭제도 가능
-> 파이어베이스: CRUD를 이미 구현해놓고, 웹에서 바로 사용할 수 있도록 서비스화까지
-> 우리는 등록과 삭제를 코드로 하기를 원함
-> 따라서 이렇게 서비스 통해서 등록한 컬렉션은 삭제!
--> 우리가 직접 컬렉션 등록할 수 있도록 코드짤 것임

4. 리액트에서 파이어베이스 데이터베이스 사용해 보기

: 파이어베이스 DB에 코드로 작성
: 지금부터 파이어베이스 데이터베이스 파이어스토어
-> 리액트에서 파이어베이스 데이터베이스 사용하려면 fbase.js 수정

  • fbase.js
    -> dpService에 firebase.firestore() 담아 export

    -> import, export 수정 후에는 서버 무조건 다시 실행!

5. 파이어스토어에 데이터 저장하기: Create

: 파이어스토어에 데이터 저장 (CRUD의 Create 구현)

  • Home.js

    -> 'dbService.collection("nweets").add'는 Promise를 반환하므로 async-await문을 사용
    -> 컬렉션 생성
    -> '.add({text: nweet, createdAt: Date.now(),})': 해당 컬렉션에 문서 생성
    -> 위의 코드: nweet 상태의 값을 문서에 text 필드로 저장. 'setNweet("");'는 nweet 상태를 다시 빈 문자열로 초기화

    -> 누이터에서 트윗한 값이 파이어스토어에 저장

⭕ 정리: fb의 db를 생성하고, 파이어베이스의 데이터베이스(파이어스토어)에 create하는 방법을 배웠다. firebase의 firestore()모듈에 있는 함수들을 이용하였다. collection 함수를 이용해 컬렉션을 생성하고, .add하여 문서를 생성했다.

6. 파이어스토어에서 문서 읽어오기: Read

: 트윗 목록 보여줌 (CRUD의 Read 구현)
-> 파이어스토어의 컬렉션과 그 안의 문서들 읽어오기
-> get함수로 문서 받아오면 됨 (문서가 여러개인 경우에 forEach)

  • Home.js

    -> 코드를 위와 같이 수정
    -> useEffect: 컴포넌트가 모두 마운트된 이후에 문서를 가져오기 위해
    -> async-await 문을 쓰는 함수가 useEffect에 포함되어 있으면, 그 함수는 따로 빼서 작성하고, useEffect에서 그 함수를 실행시켜야 함.
    -> dbService 관련 함수는 async-await 문을 사용해야 해!!
    -> get함수: 문서목록, 여러 정보 한꺼번에 반환

    -> 콘솔에 dbNweets가 출력되는데, 복잡한 데이터만 보일 뿐, 게시물 목록이 보이지 않음
    -> 스냅샷: 파이어스토어의 원본을 사진 찍듯이 찍어 보내준 것
    ---> 우리가 원하는 데이터는 스냅샷 속에 숨어있음!
    -> for each 함수 통해 얻어내야 함

    -> 스냅샷은 다시 여러 개의 문서 스냅샷으로 구성 (그 여러 개의 문서 스냅샷 순회하기 위해 forEach문)
    -> data함수: 우리가 원하는 데이터 얻을 수 있음

    -> 위와 같이 결과가 잘 나오는 것을 알 수 있다!

7. 받은 데이터로 게시물 목록 만들어 보기

: 콘솔에 데이터 출력되는거 누이터에 반영하기
-> 파이어스토어에서 받은 데이터는 상태로 관리해야 화면에 보여줄 수 있음
-> 빈 배열로 초기화한 nweets을 만들고, forEach 함수와 setNweets으로 파이어스토어의 데이터 저장

-> nweets에 데이터를 쌓고 싶다면, 위와 같이 전개구문을 이용하여! (꼭 이전 데이터 받아와서 해야함- 함수의 인자로 넘어옴)
-> 예전배열 받아와서 data 받은 후 합치고 다시 nweets 만들어줌.

8. 트윗 아이디 저장하기

: CRUD의 U, D를 구현의 명령을 위해 필요한 값인 아이디 저장
-> ID: 파이어스토어에서 데이터 구별 시 사용

9. 트윗 목록 출력해 보기

-> 배열을 Home 컴포넌트에 출력

-> 배열을 순회하면서 jsx 반환 (nweets 배열을 순회하면서 id를 key로 하여 text 출력

10. 근데..이거 누가 쓴 트윗이야?

-> 누가 쓴 트윗인지 알 수 없음
-> 트윗 수정, 삭제 기능을 위해 필요
-> app.js에서 authService.onAuthStateChanged 함수를 사용해서 로그인한 사람의 정보 받아옴
-> 이 값을 다른 컴포넌트로 전달

  • app.js

    -> useState 하나 더 만듦
    -> 그렇다면 그 userObj는 어디로?
    -> Home, Profile, EditProfile..등 여러 컴포넌트로 보내야하므로 중간 역할을하는 AppRouter로 보냄!
  • app.js

    -> 코드를 위와 같이 수정
    -> userObj를 AppRouter의 props로 전달 (AppRouter에서는 받아서 사용하면 됨)
    -> AppRouter: userObj를 받아 필요한 컴포넌트에 다시 props로 전달하면 됨
    (원래 이렇게 프롭스 여러 컴포넌트 거치지 않는게 좋음. 유지보수에 bad. but, 2단계 정도는 괜찮)
  • Router.js

    -> Router에서 userObj props로 전달
    -> Router.js에서는 다시 Home으로 props로 전달
    -> Home 컴포넌트에서는 이 값을 받아야 함
  • Home.js


    -> 트윗을 파이어스토어에 저장할 때, 사용자 정보의 id도 함께 추가할 것임! (그럼, 누가 쓴 트윗인지 함께 저장 가능)
    -> 파이어스토어에서 데이터 저장: add함수- 저장할 항목을 객체로


    -> id가 일치하는 것을 알 수 있음

⭕ 정리:
여기까지는 생성 시, 데이터베이스에 저장하고, 그 값을 콘솔-> 브라우저에 출력하고 목록을 보여주는 것을 구현 (콘솔-> 브라우저), 누가 쓴 트윗인지 연결까지

😀 실시간 데이터베이스로 트윗 목록 보여주기

: 위에서는 폼과 파이어스토어 이용해서 트윗 목록 출력
-> 트윗 추가해도 새로고침 하지 않으면 새 트윗 반영x
-> get 함수로 파이어스토어의 데이터 받아와서 (처음에 화면 렌더링 시에만 get 함수 실행)
--> 실시간 데이터베이스 이용한 트윗 목록 출력

실시간 데이터 베이스

-> 채팅 애플리케이션 만들 때 유용 (데이터베이스 변화 실시간 감지)
-> 변화감지: 파이어베이스 라이브러리 함수 실행
-> 새 트윗 바로 보여줌
-> 이 방법 도입 시, 데이터베이스와 통신 할 때 async-await 문 쓰지 않아도 됨
-> get 함수 사용 x

1. getNweets 함수 삭제하기

  • Home.js

    -> get함수는 딱 처음 한번 만 렌더링 되어서, 실시간 데이터베이스에서는 사용하지 않으므로 모두 삭제한다.

2. onSnapshot 함수 적용하기

-> onSnapShot 함수
-> 함수 하나 교체로 실시간 데이터베이스 도입

-> get함수처럼 스냅샷을 반환 (스냅샷은 문서 스냅샷들 포함)
-> snapshot.docs: 문서 스냅샷 얻기
-> map: 문서 스냅샷에서 원하는 값만 뽑아 다시 배열화 (효율적-순회하며 만든 배열을 반환)

-----> 여기까지는 트윗 등록(콘솔-> 브라우저), 트윗 쓴 사람 반영, 목록 출력, 실시간으로 브라우저에 반영(snapshot함수),

😀 트윗 삭제 기능 만들기 (delete 함수)

1. 트윗 컴포넌트 분리하기

: 트윗 바로 아래 수정, 삭제 버튼 두려면 Home 컴포넌트 너무 복잡해짐
-> 리액트에서 컴포넌트 덩치 효율적으로 줄이는 것 중요
-> 트윗 출력 부분을 컴포넌트 분리

-> 윗 부분을 Nweet 컴포넌트

  • Nweet.js
  • Home.js

    -> 트윗 출력 시, Nweet 컴포넌트 호출 (id를 키로해서, nweet를 props로 전달-> Nweet.js에서는 Home 컴포넌트의 map함수에서 반환하는 nweetObj 배열을 props로 받음)
    -> nweets의 요소들 하나씩 접근하면서, 그 해당 요소를 nweet로 두고, 그 값을 전달해주어 Nweet 컴포넌트를 실행하여 출력되게 함)

2. 트윗 <수정>, 트윗 <삭제> 버튼 추가하기

-> 수정, 삭제를 위해서 컴포넌트 분리해주었으니, '수정', '삭제' 버튼 추가


-> 이렇게 버튼 생성 완료

3. 내가 쓴 트윗은 나만 지우거나 수정할 수 있도록 만들기

: 트윗을 쓴 사람만 트윗을 삭제하거나 수정하도록 (creatorId-트윗 쓴 사람의 id, 현재 로그인한 사람의 uid 비교)
-> 같으면 수정, 삭제 버튼 보여줌

  • userObj: 현재 로그인한 사용자
  • creatorId: 트윗 쓴 사람의 아이디

    -> 주인인 경우에만, 수정 삭제 버튼 뜨게 하기 위해, 출력 컴포넌트인 Nweet으로 isOwner를 props로 넘겨줌
  • Nweet.js

    -> &&연산자를 이용하여 true인 경우에만, 버튼 들이 뜨게 하였다.
    --> 다른 아이디로 로그인했을 때, 수정 삭제 버튼 뜨는지 확인하기! (아직 버튼 눌렀을 때의 동작은 없음)

5. 버튼에서 삭제 기능 추가하기

: 파이어베이스 라이브러리 함수 이용
-> 문서의 id 이용해서 삭제 (Home 컴포넌트에서 Nweet 컴포넌트에 props로 넘긴 nweetObj에 문서 아이디)

파이어스토어 구조

: 컬렉션의 집합
-> 우리가 사용하는 컬렉션의 이름 nweets이고, 이 컬렉션에는 데이터 (문서)가 들어있음
-> 즉, 우리는 nweets에 데이터(문서)를 추가하고 삭제하고 있는 것임!

  • Nweet.js



    -> 삭제 버튼을 누르면, onDeleteClick 함수 실행하고 '삭제하시겠습니까?' 문구 뜨게 함
    -> window.confirm: <확인>-> true/ <취소>-> false

  • 삭제 버튼 누르면 트윗 삭제하도록! (Nweet.js)

    -> ok 버튼이 true이면, 트윗 문서 아이디 콘솔에 출력해주고, 삭제할 스냅(문서)를 data에 저장해서, 콘솔에 출력해줌
    -> 즉, 문서를 가져오고 있음
    *리터럴 문법: 문자열 사이에 변수가 존재할 때 쉽게 나타내는 방법
    -> doc함수: 문서 경로를 문자열로 입력 받아서 문서 반환

    -> 이렇게 delete 함수만 넣어주면 삭제!

😀 트윗 수정 기능 만들기 (update함수-객체 형태로)

: 기존 트윗이 남아있으면서도 수정할 수 있는 형태로 입력란 변화/ 확인, 취소 버튼

1. 수정 기능을 위한 useState 추가하기

  • editing: <수정> 버튼을 눌렀을 때 입력란과 버튼이 나타나는 기준점
  • newNweet: 입력란에 기존 트윗이 보이도록 초깃값을 관리하기 위한 상태

    -> editing에 따라서 토글할 수 있게 화면 구성 (원래 false였는데, edit버튼 누르면 수정하는 상태라는 것을 나타냄)

    -> 수정 버튼 누르면, toggleEditing 함수에 의해서 토글이 되어 editing이 true가 되면서 삼항 연산자 왼쪽 부분 수행


-> 토글할 때 이 구문 기억하기!!! 상태로 true, false 저장해두고, return 문 안에서 그 값에 따라 삼항연산자로 화면에 보일값 구성

-> 기존 트윗 입력된 상태에서 수정 시작 가능!


-> 기존값을 저장해서 value로 넘기기 때문

2. 입력란에 onChange 작업하기

!!입력란에 테스트 입력해야하는 경우: onChange props, 함수 작업 필수!!


-> 이렇게 onChange 함수 추가해준다
-> onChange 함수 형태는 외우자 그냥!!!
-> input란이 변경되면, 그 키보드값이 value로 넘어가고, 그 value는 setNewNweet통해서 newNweet에 반영

3. 파이어스토어에 새 입력값 반영하기

: form element와 onSubmit 함수 필요

-> 위와 같이 수정 후, 업데이트 버튼 누르면 onSubmit 함수 실행
-> 함수 실행 시: 트윗 아이디, 입력한 텍스트 파이어스토어로

-> 아이디, 텍스트 잘 출력

  • 이제 파이어스토어에서 '이 문서의 이 값을 수정해주세요'요청하기!

    -> doc함수를 통해 문서를 찾아 업데이트 요청!
    -> 업데이트 값을 { } 이렇게 객체로 전달해야 함!
    -> 그 다음 editing을 false로 바꾸어 toggle을 변경

⭕ 정리:
이번 5장에서는 누이터의 핵심 기능인 트윗의 CRUD를 구현하였다.
1. 트윗 등록 (create)
: 파이어데이터 베이스 사용하기

  • fbase에서 firestore()모듈 받아오기 (dbService)
  • collection.add()를 통해서: 컬렉션 생성하고, 데이터베이스에 생성
  1. 트윗 목록 조회 (Read)
  • get함수-> data() : 스냅샷 속에 숨겨진 데이터 가져옴(forEach)

  • 여러개의 트윗 데이터: nweets에 저장(예전 배열 이용)

  • 배열의 데이터들 map함수로 출력

  • 누가 쓴 트윗인지: auth에서 userObj로 받아옴 (Router로 전달해서 필요한 곳에서 사용)-> 파이어스토어에 저장 시 같이 저장

  • 실시간으로 트윗 내용 보여주기 위해서 get 대신 onSnapshot!!

  • 트윗 아이디 저장 (누가 쓴 트윗인지)

  1. 트윗 삭제 (delete)
  • 버튼 추가: 파이어스토어에 저장한 트윗한 사람과 로그인 정보가 같은 경우에만 버튼 뜨도록)
  • 삭제버튼 누르면-> 삭제하겠냐는 문구 나오고-> true이면 -> 파이어스토어의 그 해당 아이디에 해당하는 문서 가지고 와서 delete()함수
  1. 트윗 업데이트(update)
    : 수정 상태와 아닌상태 토글 변경을 위해 상태추가(editing)
    -> return에 각각에 대한 화면 구성
    -> 수정 상태인 경우: 새 input란으로 바뀌고(기존값에서 시작) 변경과 취소 버튼 (취소이면 다시, 토글 변경)
  • 변경 버튼: update함수로 특정 문서의 text를 변경하도록 객체로 전달
  • onChange: 입력란 변경, newNweet 값 업데이트
  • onSubmit: 파이어스토어에서 특정 문서 가져와서 값 변경

----> 등록(add)/조회(get,onSnapshot)/삭제(delete)/수정(update)
-----> 입력란 변경 시에는 onChange함수 무조건
---> 결괏값 반영에는 onSubmit함수 무조건

!!입력란에 테스트 입력해야하는 경우: onChange props, 함수 작업 필수!!
!! 입력란 결괏값 변경하는 경우: for, onSubmit 함수 (async-await으로!!

profile
지수의 취준, 개발일기
post-custom-banner

0개의 댓글