본문 바로가기
Web Service/React

[트위터 클론 코딩] #4. Nweeting-Create, Read

by junnykim 2022. 4. 1.

~3.3까지의 강의

 

로그인 하면 나오는 Home에서 tweet용으로 form을 하나 만들것이다.

 

Home.js

import React,{useState} from "react";

const Home = () => {
    const [nweet, setNweet] = useState("");
    const onSubmit = (event) => {
      event.preventDefault();
    };
    const onChange = (event) => {
      const {
        target: { value },
      } = event;
      setNweet(value);
    };
    return (
      <div>
        <form onSubmit={onSubmit}>
          <input
            value={nweet}
            onChange={onChange}
            type="text"
            placeholder="What's on your mind?"
            maxLength={120}
          />
          <input type="submit" value="Nweet" />
        </form>
      </div>
    );
  };
export default Home;

앞에서 설명했던 거랑 비슷한 코드가 너무 많아서, 딱히 설명할 것은 없는 듯

로그인 하면 실행되는 페이지

 

이제 Firestore Database로 가서, 데이터베이스를 만들어주자.

데이터베이스 만들기를 클릭하면 오른쪽과 같은 화면이 뜬다. 우리는 테스트 모드로 할것이고, 옆에 있는 것은 우선 무시

 

그 후 fbase로 가서 import "firebase/compat/firestore"를 해준다.

우리가 사용하고자 하는 것은 꼭 import해주어야 한다.

 

database가 생성되었다.

 


 

database가 생성되었는데, 규칙들이 없어서 제한되는 경우가 있다.

제한사항을 살펴보자.

 

firestore nosql이 가지는 특징

1. collection은 폴더
2.document는 컴퓨터 문서

collection은 document를 가지고 있다. 

 

코드를 짜지 않고도, 직접 만들어 줄 수 있다.

nweets라는 collection밑에 document가 있는 것이다. collection은 documnet의 그룹이다.

 

자 이제 코드를 짜서 해보자.

fbase.js로 가서 export const dbService = firebase.firestore(); 를 마지막에 입력해준다.

 

우리는 dbService를 사용해 submit 할 때마다 document를 생성할 것이다.

Home.js

import React,{useState} from "react";
import { dbService } from "fbase";

    const onSubmit = async (event) => {
      event.preventDefault();
      await dbService.collection("nweets").add({
        nweet,
        createdAt: Date.now(),
      });
      setNweet("");
    };

 

공식 문서를 보면, firestore페이지에서 doc과 collection이 있다.

 

collection은 위치를 지정해주어야 하기 때문에,

dbService.collection을 적어주고, 우리의 collection이름인 nweets를 적어준다.

nweets밑에 많은 것들이 있는데, 추가할 거니까 add를 해준다.

 

add에 원하는 것을 적어주면 되는데,

리의 key(=value)인 nweet와 언제 만들었는지 알 수 잇는 createdAt: Date.now()를 적어준다.

 

submit을 하고 하면 setNweet를 해줘야 한다.

실시간으로 생성되는 것을 확인하기위해 async와 await를 적어준다.

 

 

nweet 컬렉션과 랜덤 id를 생성할 수 있게 되었다.

 


nweets를 어떻게 가져올 것인가?에 대해서 알아보도록 하자.

 

Home.js

import React,{useState, useEffect } from "react";
import { dbService } from "fbase";

const Home = () => {
    const [nweet, setNweet] = useState("");
    const [nweets, setNweets] = useState([]);
    const getNweets = async () => {
    const dbNweets = await dbService.collection("nweets").get();
    dbNweets.forEach((document) => {
      const nweetObject = {
        ...document.data(),
        id: document.id,
      };
      setNweets((prev) => [nweetObject, ...prev]);
    });
  };
  useEffect(() => {
    getNweets();
  }, []);
    const onSubmit = async (event) => {
      event.preventDefault();
      await dbService.collection("nweets").add({
        nweet,
        createdAt: Date.now(),
      });
      setNweet("");
    };
    const onChange = (event) => {
      const {
        target: { value },
      } = event;
      setNweet(value);
    };
    console.log(nweets);
    return (
      <div>
        <form onSubmit={onSubmit}>
          <input
            value={nweet}
            onChange={onChange}
            type="text"
            placeholder="What's on your mind?"
            maxLength={120}
          />
          <input type="submit" value="Nweet" />
        </form>
        <div>
        {nweets.map((nweet) => (
          <div key={nweet.id}>
            <h4>{nweet.nweet}</h4>
          </div>
        ))}
      </div>
      </div>
    );
  };
export default Home;

const nweets, setNweet를 만들고 useState를 지정해주고, component가 mount되면 useEffect를 사용한다.

 

getNweets

dbService를 가지고 와서 .찍고 nweets 다음에 get을 해준다.

이 부분은 async를 사용해야 하기 때문에, 개별 함수이어야 한다.

공식 문서의 get은 Query snapshot을 return한다.

 

실행 결과

 


 

 

사용자가 누구인지 알고 싶다.

 

App.js

import React, { useState, useEffect } from "react";
import AppRouter from "components/Router";
import { authService } from "fbase";


function App() {
  const [init, setInit] = useState(false);
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [userObj, setUserObj] = useState(null);
  useEffect(() => {
    authService.onAuthStateChanged((user) => {
      if (user) {
        setIsLoggedIn(true);
        setUserObj(user);
      } else {
        setIsLoggedIn(false);
      }
      setInit(true);
    });
  }, []);
  return (
    <>
      {init ? (
        <AppRouter isLoggedIn={isLoggedIn} userObj={userObj} />
      ) : (
        "Initializing..."
      )}
      <footer>&copy; {new Date().getFullYear()} Nwitter</footer>
    </>
  );
}

export default App;

 

userObj를 만들어 사용자가 누구인지 알 수 있게 해주자.

만약 authService가 바뀐다면, 우리가 받을 user에 setUserObj를 넣어준다.

 

return문을 보면, 로그인 되면 onAuthStateChanged가 호출된다.

로그인 정보와 user의 정보를 Router에 전달한다.

 

Router.js

import React from "react";
import { HashRouter as Router, Route, Switch } from "react-router-dom";
import Auth from "routes/Auth";
import Home from "routes/Home";
import Profile from "routes/Profile";
import Navigation from "components/Navigation";


const AppRouter = ({ isLoggedIn, userObj }) => {
  return (
    <Router>
      {isLoggedIn && <Navigation />}
      <Switch>
        {isLoggedIn ? (
          <>
            <Route exact path="/">
              <Home userObj={userObj} />
            </Route>
            <Route exact path="/profile">
              <Profile />
            </Route>
          </>
        ) : (
          <>
            <Route exact path="/">
              <Auth />
            </Route>
          </>
          
        )}
      </Switch>
    </Router>
  );
};
export default AppRouter;

받은 userObj와 로그인 정보를 Home에 보내준다.

 

Home.js

import React,{useState, useEffect } from "react";
import { dbService } from "fbase";

const Home = ({ userObj }) => {
    const [nweet, setNweet] = useState("");
    const [nweets, setNweets] = useState([]);
  
  useEffect(() => {
    dbService.collection("nweets").onSnapshot((snapshot) => {
      const nweetArray = snapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      }));
      setNweets(nweetArray);
    });
  }, []);
    const onSubmit = async (event) => {
      event.preventDefault();
      await dbService.collection("nweets").add({
        text: nweet,
        createdAt: Date.now(),
        creatorId: userObj.uid,
      });
      setNweet("");
    };
    const onChange = (event) => {
      const {
        target: { value },
      } = event;
      setNweet(value);
    };

    return (
      <div>
        <form onSubmit={onSubmit}>
          <input
            value={nweet}
            onChange={onChange}
            type="text"
            placeholder="What's on your mind?"
            maxLength={120}
          />
          <input type="submit" value="Nweet" />
        </form>
        <div>
        {nweets.map((nweet) => (
          <div key={nweet.id}>
            <h4>{nweet.text}</h4>
          </div>
        ))}
      </div>
      </div>
    );
  };
export default Home;

userObj를 통해 누가 로그인 했는지 알 수 있다.

 

그리고, creatorId를 생성해 uid를 추가한다.

 

정보를 가져오는 것을 snapshot을 사용한다.

dbService.collection("nweets").onSnapshot((~ 은 우리가 페이지를 불러올 떄 사용한다.

 

user Id가 생성된 것을 확인할 수 있다.

 

필드의 값만 code대로 text로 해주면 직접 추가할 수도 있다.

 

댓글