상세 컨텐츠

본문 제목

[Twitter Clone Coding] #5 EDIT PROFILE

Twitter Clone Coding

by jer0618 2022. 11. 9. 07:56

본문

https://nomadcoders.co/nwitter

 

트위터 클론코딩 – 노마드 코더 Nomad Coders

React Firebase for Beginners

nomadcoders.co

*노마드코더 트위터 클론코딩 강의내용을 정리한 글입니다. 

**강의에서는 Firebase v8 를 사용했지만 여기서는 Firebase v9을 사용하여 구현했습니다.

 

Get My Own Nweets

https://firebase.google.com/docs/firestore/query-data/queries

https://firebase.google.com/docs/firestore/query-data/order-limit-data

  • 쿼리문을 작성하여 나의 Nweets를 가져옴
  • query 함수내 인자로 where함수를 사용해 필터링
  • where함수 및 orderBy, limit함수를 함께 인자로 넣어 정렬과 개수제한도 가능
// Profile.js
// ...
const getMyNweets = async () => {

		// 내가 작성한 데이터를 시간순으로 오름차순 정렬하여 가져옴
    const q = query(
			collection(fbStore, "nweets"), 
			where("creatorId", "==", userInfo.uid), 
			orderBy("createdAt")
		);

    const nweets = await getDocs(q);
    console.log(nweets.docs.map((doc) => doc.data()));
  };

  useEffect(() => {
    getMyNweets();
  }, []);
// ...

색인 생성

https://console.firebase.google.com/project/nwitter-9aeb9/firestore/indexes

  • fireStrore는 noSQL기반 DB이기 떄문에 복합쿼리를 실행하기 위해서는 미리 복합쿼리에 대한 색인(index)을 생성해줘야함

  • 설정완료 (시간이 좀 걸림)

Update Profile

https://firebase.google.com/docs/auth/web/manage-users

  • updateProfile 함수를 사용해 displayName과 photoURL 변경가능
  • Firebase의 한계 ⇒ userInfo에 많은것을 담을 수 없음
// Profile.js
// ...

const onSubmitHandler = async (event) => {
    event.preventDefault();

    if (userInfo.displayName === newDisplayName) return;

    await updateProfile(userInfo, { displayName: newDisplayName, photoURL: "" });
  };

// ...
  • 변경됭 displayName을 적용시키기 위해서 새로 렌더링해야함
  • 유저 정보를 새로고침하는 함수 생성 → Profile 컴포넌트까지 함수를 내려줌
  • Profile에서 유저정보를 변경시킬때 함수를 실행시켜줌
// App.js
// ...

const refreshUser = () => {
    setUserInfo(fbAuth.currentUser);
  };

// ...

return (
    <div>
      {loading ? `loading...` : <Router refreshUser={refreshUser} isLoggedIn={isLoggedIn} userInfo={userInfo} />}
      <footer>&copy; {new Date().getFullYear()} Nwitter</footer>
    </div>
  );

// ...
// Profile.js
// ...

const onSubmitHandler = async (event) => {
    event.preventDefault();

    if (userInfo.displayName === newDisplayName) return;

    await updateProfile(userInfo, { displayName: newDisplayName, photoURL: "" });
    refreshUser();
  };
// ...

⇒ userInfo는 방대한 정보를 담고있는 객체이기 때문에 react에서 변경점을 찾지 못해 재랜더링이 되지 않을 수 있음

⇒ 해결법

  1. 사용할 userInfo의 크기 줄이기
    // App.js
    // ...
    
    const refreshUser = () => {
        // setUserInfo(fbAuth.currentUser);
        const user = fbAuth.currentUser;
    		// 실제 사용할 정보만 userInfo에 저장해서 사용
        setUserInfo({
          displayName: user.displayName,
          uid: user.uid,
          updateProfile: (args) => user.updateProfile(args),
        });
      };
    
      useEffect(() => {
        onAuthStateChanged(fbAuth, (user) => {
          if (user) {
            setIsLoggedIn(true);
            // setUserInfo(user);
            setUserInfo({
              displayName: user.displayName,
              uid: user.uid,
              updateProfile: (args) => user.updateProfile(args),
            });
          } else {
            setIsLoggedIn(false);
            setUserInfo(null);
          }
    
          setLoading(false);
        });
      }, []);
    
    // ...
    
    ⇒ v9에서는 updateProfile에 userInfo를 사용하므로 위 방법(강의내용)으로는 변경안됨 ⇒ 추가적인 작업 필요
    ⇒ 실제 사용하는 정보만 저장해서 사용
  2. Object.assign을 사용해 변경하기
    // App.js
    // ...
    
    const refreshUser = () => {
        setUserInfo(Object.assign({}, fbAuth.currentUser));
      };
    
    // ...
    
    ⇒ Object.assign을 사용해 새로운 객체를 생성하여 React가 새로 렌더링 하도록 할 수 있음
반응형

관련글 더보기