TIL_230213 MyProfile에 닉네임 수정

그래도 해야지·2023년 2월 13일
0

TIL

목록 보기
35/44

☠️ 문제 1

  • 닉네임을 받아오긴 하는데 새로고침을 하면 닉네임이 ui에서 없어진다.
  • 닉네임이 안 보이는 상태에서 컴포넌트 수정을 하고 다시 저장을 해야지만 ui에서 보인다.
import { useState, useEffect } from 'react';
// firebase auth에서 닉네임, 유저 아이디등을 받아올 수 있도록 import함
import { auth } from '../../services/firebase';
import {
  MyProfileWrapper,
  MyProfileImage,
  MyProfileNickname,
  NicknameModifyBox,
  ModifyButton,
  DeleteAccountBtn,
  PasswordChange,
  NicknameInput,
} from './style';

const MyProfile = () => {
  const [nickname, setNickname] = useState<string | null | undefined>(''); 

  useEffect(() => {
    const userName = auth.currentUser?.displayName;   
    setNickname(userName);
  }, [nickname]);


  return (
    <MyProfileWrapper>
      <MyProfileImage>이미지</MyProfileImage>
      <MyProfileNickname>{auth.currentUser?.displayName}</MyProfileNickname>
      <NicknameModifyBox>
        <NicknameInput placeholder="닉네임을 입력해주세요"></NicknameInput>
        <ModifyButton>수정</ModifyButton>
      </NicknameModifyBox>

      <DeleteAccountBtn>회원탈퇴</DeleteAccountBtn>
      <PasswordChange>비밀번호 변경</PasswordChange>
    </MyProfileWrapper>
  );
};

export default MyProfile;

👩🏻‍💻 시도해본 것들, 원인

  • 로그인이 되어있는지 상태를 받아와야하는데 새로고침을 하면서 그게 풀린다.
  • 그걸 recoil은 자동적으로 확인하고 recoil이 없으면 useSelector를 써서 로그인 상태를 받아와야하는데 그게 안되어있어서 로그인 상태가 확인이 안 되니까 닉네임이 새로고침하면 보이질 않는 것이다.

👩🏻‍🎓 해결

  • recoil을 사용했더니 해결되었다.

Q. 왜 해결이 되었나?

recoil을 사용하면 로그인된 상태를 자동으로 확인이 되기 때문에 로그인 된 유저아이디의 닉네임도 받아올 수 있는 것

useRecoilValue(state)란?

주어진 Recoil 상태의 값을 리턴합니다.
이 hook은 암묵적으로 주어진 상태에 컴포넌트를 구독합니다.

  • state : atom 혹은 selector
import { useRecoilValue } from 'recoil';
import { userInfo } from '../../atoms';
import {
  MyProfileWrapper,
  MyProfileImage,
  MyProfileNickname,
  NicknameModifyBox,
  ModifyButton,
  DeleteAccountBtn,
  PasswordChange,
  NicknameInput,
} from './style';

const MyProfile = () => {
	// useRecoilValue 기능으로 userInfo를 받아옴 
  const user = useRecoilValue(userInfo);

  return (
    <MyProfileWrapper>
      <MyProfileImage>이미지</MyProfileImage>
      <MyProfileNickname>{user.userInfomation.displayName}</MyProfileNickname>
      <NicknameModifyBox>
        <NicknameInput placeholder="닉네임을 입력해주세요"></NicknameInput>
        <ModifyButton>수정</ModifyButton>
      </NicknameModifyBox>

      <DeleteAccountBtn>회원탈퇴</DeleteAccountBtn>
      <PasswordChange>비밀번호 변경</PasswordChange>
    </MyProfileWrapper>
  );
};

export default MyProfile;
  • 재창님이 미리 만들어 놓으신 UserInformation을 사용하면 해결!
// atom.ts
import { atom } from 'recoil';

interface UserInfomation {
  displayName: string;
  email: string;
  photoURL: string;
  uid: string;
}

✅ 알게된 점

recoil을 쓰는 이유를 알게 되었다.

  • recoil을 안쓰면 이렇게 긴데
const [nickname, setNickname] = useState<any>('');
  // useRecoilValue 기능으로 userInfo를 받아옴
  // const user = useRecoilValue(userInfo);
  useEffect(() => {
    onAuthStateChanged(auth, (user) => {
      if (user) {
        setNickname(auth.currentUser?.displayName);
        console.log('로그인 되어있음');
      } else if (!user) {
        console.log('로그인 안됨');
      }
    });
    if (!nickname) return;
  }, []);

-recoil은 한줄로 가능하다.

  const user = useRecoilValue(userInfo);

📚 Today Study

input에 입력되는 값 받기 (typescript)

const MyProfile = () => {
  const [nickname, setNickname] = useState<string>('');

  const user = useRecoilValue(userInfo);

  // 인풋하는 족족 데이터 받고 수정
  const NicknameChangeInput = (event: any) => {
    console.log(event.target.value);
    setNickname(event.target.value);
  };

  return (
        <NicknameInput
          onChange={NicknameChangeInput}
          placeholder="닉네임을 입력해주세요"
        />

onAuthStateChanged에서 받아오는 user가 뭘까?

  • onAuthStateChanged는 파베에서 제공하는 함수인데 그 함수에 user값이 포함되어 있는 건지 궁금해서 ddong이라는 이름으로 바꿔서 받아왔더니 둘다 UserImpl 객체로 떴다.

⭐onAuthStateChanged에서 받아오는 user는 어떤 이름을 써도 된다

왜 어떤 이름을 써도 되는걸까? ⭐꼭 내일하기

// 로그인 상태인지 확인 함수

  useEffect(() => {
    auth.onAuthStateChanged((ddong) => {
      // auth = getAuth() : currentUser이 담겨있는 배열(AuthImpl)
      // user : displayName이 담겨있는 객체(UserImpl)
      console.log('ddong', ddong);
      if (ddong) {
        console.log('auth.currentUser', auth.currentUser);
        setCurrentUser(auth.currentUser);
        // auth.currentUser : displayName이 담겨있는 객체(UserImpl)
        // setCurrentUser : 함수?같은 건데 잘 모르겠음
        setNickname(auth.currentUser?.displayName);

        console.log(
          'auth.currentUser?.displayName',
          auth.currentUser?.displayName,
        );
        //auth.currentUser?.displayName : 원래 닉네임
        console.log('로그인 되어있음');
      } else if (!ddong) {
        console.log('로그인 안됨');
      }
    });
    if (!currentUser) return;
  }, []);
  

📝 Today Review

닉네임 수정 잘 되는 코드

//MyProfile.tsx
import { onAuthStateChanged } from 'firebase/auth';
import { useEffect, useState, useCallback } from 'react';
import { useRecoilValue } from 'recoil';
import { userInfo } from '../../atoms';
import { auth } from '../../services/firebase';
import {
  MyProfileWrapper,
  MyProfileImage,
  MyProfileNickname,
  NicknameModifyBox,
  ModifyButton,
  DeleteAccountBtn,
  PasswordChange,
  NicknameInput,
  Colortext,
} from './style';
import { updateProfile } from 'firebase/auth';

const MyProfile = () => {
  // nickname : 현재 nickname이 들어옴
  const [nickname, setNickname] = useState<any>('');
  console.log('nickname', nickname);

  // currentUser : displayName이 담겨있는 객체
  const [currentUser, setCurrentUser] = useState<any>('');

  // useRecoilValue 기능으로 userInfo를 받아옴
  // const user = useRecoilValue(userInfo);

  // 로그인 상태인지 확인 함수
  useEffect(() => {
    auth.onAuthStateChanged((user) => {
      // auth = getAuth() : currentUser이 담겨있는 배열(AuthImpl)
      // user : displayName이 담겨있는 객체(UserImpl)

      if (user) {
        console.log('auth.currentUser', auth.currentUser);
        setCurrentUser(auth.currentUser);
        // auth.currentUser : displayName이 담겨있는 객체(UserImpl)
        // setCurrentUser : 함수?같은 건데 잘 모르겠음
        setNickname(auth.currentUser?.displayName);

        console.log(
          'auth.currentUser?.displayName',
          auth.currentUser?.displayName,
        );
        //auth.currentUser?.displayName : 원래 닉네임
        console.log('로그인 되어있음');
      } else if (!user) {
        console.log('로그인 안됨');
      }
    });
    if (!currentUser) return;
  }, []);

  // 닉네임 바꿔주는 함수
  // auth와 getAuth()는 같음

  const onClick = async () => {
    await updateProfile(currentUser, {
      displayName: nickname,
      photoURL: 'https://example.com/jane-q-user/profile.jpg',
    })
      .then(() => {
        setNickname('');
        console.log('nickname=>', nickname);
        alert('Profile updated!');
      })
      .catch((error) => {
        console.log('An error occurred');
      });
  };
  // 인풋에 입력한 상태 그대로 ui표시
  // onchange는 매번 set을 해주는 것
  const NicknameChangeInput = (event: any) => {
    setNickname(event.target.value);
    console.log('event.target.value', event.target.value);
  };

  return (
    <MyProfileWrapper>
      <MyProfileImage>이미지</MyProfileImage>
      <MyProfileNickname>{currentUser?.displayName}</MyProfileNickname>
      <NicknameModifyBox>
        <NicknameInput
          placeholder="닉네임을 입력해주세요"
          onChange={NicknameChangeInput}
          value={nickname}
        />

        <ModifyButton onClick={onClick}>수정</ModifyButton>
      </NicknameModifyBox>

      <DeleteAccountBtn>회원탈퇴</DeleteAccountBtn>
      <PasswordChange>비밀번호 변경</PasswordChange>
    </MyProfileWrapper>
  );
};

export default MyProfile;

https://wakestand.tistory.com/851

implementation - 실제구현체

0개의 댓글