본문으로 건너뛰기

Study

onKeyPress

평소엔 input창에 입력하고 enter를 입력하면 insert 버튼이 눌리는데,
edit 버튼을 누르면 insert, delete 버튼 두 개가 나와서 그런지 enter가 눌리지 않았다.

<Input
value={editContent}
ref={inputRef}
className="memoList_input"
onChange={contentHandler}
onKeyPress={inputPressHandler}
></Input>

onKeyPress를 추가해 input에 focus 되어있을 때 inputPress Handler를 실행시키고,

const inputPressHandler = (e) => {
if (e.key === "Enter") contentChangeHandler();
};

press된 key가 Enter라면 insert버튼이 onClick되었을 때 실행되는 함수와 똑같은 함수를 불렀다.

Background 클릭시 모달 종료

ref를 통해 해결했다.

const modalhandler = (e) => {
if (outside.current === e.target) onClose();
};
<div className="memoModal_background" onClick={modalhandler} ref={outside}>

background에 ref를 추가하고, 클릭시 현재 눌린 위치가 background 인지 확인, 일치하다면 닫히게 만들었다.

firebase

컴포넌트 내에서 정의한 객체를 가져왔기 때문에 새로고침을 하면 CRUD한 정보가 날라가고 초기값이 나온다.
정상적인 웹처럼 작동하기 위해 backend인 firebase와 연동을 하고 싶었고, firebase의 CRUD를 해봤다.


그 전에 firebase는 비동기처리를 하기에, 비동기처리에 대한 개요만 공부했다. 사실 들었다.

비동기 처리

then이나, addDoc등은 promise객체를 반환한다. promise 객체를 반환한다는 것은 무슨 뜻일까?
컴파일러가 실행을 위해 읽어 가다가, firebase에서 정보를 얻기 위해 서버에다가 정보를 요청한다.
서버는 지금 내가 작업하는 로컬환경과는 떨어진 곳에 있으므로 어느정도 시간이 소요된다.
서버에서 정보를 받을 때까지 기다리는 것은 굉장히 비효율적이므로, 값을 반환 받을 것을 약속(promise)하고 다음 줄을 컴파일 한다.
이게 간략한 promise, 비동기 처리의 의미이다.
기본적으로 then을 쓸 수도 있는데, async와 await을 많이 쓴다. 함수를 await으로 감싸고, 반환 받아야 하는 promise객체는 await을 붙여준다.
이렇게 해서 비동기 처리되는 코드도 동기처리되는 코드처럼 보이게하여 코드의 가독성을 높인다.


이 과정에서 try,catch를 사용할 수 있다.
promise 객체를 서버에 요구하고, pending 되었다가 이행(fulfill)되거나 거절(reject)된다.
이행되면 요구한 정보를 정확히 전달한 거라 정상적으로 실행이 되지만, 거절된다면 이상한 정보가 전달된 것이므로 error가 반환된다.
await 관련 함수들을 try{}로 묶은 상태에서 error가 반환된다면 catch(error){}가 이를 잡아서 error호출을 돕는다.

DB 구조

컬렉션 - 문서 - 필드의 구조로 되어 있다.
컬렉션이 일종으 폴더처럼 생각할 수 있어서, 원하는 문서들을 묶어서 관리할 수 있다.

import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: "",
};

// firebaseConfig 정보로 firebase 시작
const app = initializeApp(firebaseConfig);

// firebase의 firestore 인스턴스를 변수에 저장
export const db = getFirestore(app);

firebase.js를 정의하고 이를 import 시켜 호출 할 수있다.

import { db } from "./firebase";
import {
collection,
setDoc,
getDocs,
doc,
updateDoc,
deleteDoc,
} from "firebase/firestore";

db를 가져오고, 원하는 함수명을 정의하여 사용한다.

Create

async function c() {
try {
//db의 posts 컬렉션에 문서명 won의 객체를 만듦
const docRef = doc(db, "posts", "won");
//문서의 필드값들 지정
await setDoc(docRef, {
title: "행궁둥이",
content: "행궁동에서는 공방이 그렇게 많대요",
});
} catch (err) {
console.error("Error:", err);
}
}

원래 쓰는 함수가 addDoc인 거 같은데, 이는 문서의 이름을 지정할 수 없었다. setDoc의 3번째 인자로 이름을 지정하여 사용했다.

docRef로 반환 받을 때 getDocs 혹은 doc을 사용하던데 둘의 반환값이 다른 것같아 찾아봤더니
getDocs는 여러 문서를 처리하는데 사용되는 객체를 반환(snapShot 반환) doc은 단일문서를 가리키는 참조객체를 반환(reference 반환)했다.
즉 read에서는 getDocs, 나머지는 doc을 쓰는게 합리적이다.

Read

const r = async () => {
try {
//db의 post 컬렉션의 문서객체들을 받아옴
const querySnapshot = await getDocs(collection(db, "posts"));
querySnapshot.forEach((doc) => {
//id는 문서이름
console.log(doc.id, "=>", doc.data());
});
} catch (error) {
console.error("Error fetching data: ", error);
}
};

Update

const U = async () => {
try {
//원하는 컬렉션의 문서이름을 호출
const docRef = doc(db, "posts", "eunsu");
//호출된 문서의 필드값 변경
await updateDoc(docRef, { title: "hello" });
console.log("Document updated successfully.");
} catch (error) {
console.error("Error updating document: ", error);
}
};

Delete

const d = async () => {
try {
//원하는 컬렉션의 문서이름 호출
const docRef = doc(db, "posts", "queen");
// 삭제
await deleteDoc(docRef);
console.log("Document deleted successfully.");
} catch (error) {
console.error("Error deleting document: ", error);
}
};

내일은 웹에 직접 연결시켜 보는 걸로.

I

행궁동

행궁동 계획을 다 짰다. 그 날 비가 온다는데 조금 왔으면 좋겠다.ㅠㅠ

테르메덴

친구들과 테르메덴을 가기로 했다. 가서 놀고 맛있는 이천쌀 먹고올 예정.

아플 때

아플 떄 힘이 되어주고 싶은데 어렵다. 가만히 있기? 살짝 호들갑 떨면서 도와주기?

걱정과 위로

너무 걱정하면 오히려 훈수두는 거 같고 그런데, 걱정이 되면 어쩔 수 없는데. 인생은 밸런스 게임이 아닐까?

틈새라면

처음으로 틈새라면 체인점을 갔는데 순한맛을 먹었음에도 매웠다. 맵찔이 ㅇㅈ

맞춰가기