🔗 사전기획

 

[팀프로젝트] 리액트로 뉴스피드 웹사이트 제작하기 - 사전기획

리액트로 첫 팀프로젝트가 시작됐다. 뭔가 프로젝트다운 프로젝트를 하는 것 같다. 인스타그램이나 페이스북,  블로그 같이 게시글을 쓰고 읽고 수정하고 삭제할 수 있는 뉴스피드 웹사이트를

ejunyang.tistory.com

 

 

 

 

 

 

마이페이지 구현

마이페이지에 필요한 기능을 정리해보았다.

1. 로그인한 사용자의 데이터 가져오기 => id, nickname, 프로필 이미지
2. 사용자가 쓴 게시글 데이터 가져오기
3. 사용자가 좋아요 누른 게시글 데이터 가져오기
4. 사용자가 저장한 북마크 게시글 데이터 가져오기

 

 

 

컴포넌트 분리

아래와 같이 컴포넌트를 나누었다.

 

 

 

 

사용자 데이터 가져오기

 

준혁님께서 Auth.api 를 만들어주셔서 getUser를 가지고와서 사용했다. 

export const getUser = async () => {
  try {
    const {
      data: { user },
      error
    } = await supabase.auth.getUser();

    if (error) {
      console.log('Error:', error);
      return null;
    }

    // console.log('User data:', user);
    return user;
  } catch (error) {
    console.log('Error:', error);
    return null;
  }
};

 

마이페이지에서 화면에 보여줘야할 정보가 프로필 이미지와 닉네임이었기때문에 프로필 이미지와 닉네임은 useState 를 사용해줬다. 그리고 이번 과제를 하면서 supabase를 처음 다루어보았는데 우리가 Auth 테이블과 member 테이블 두개를 만들어놓은 상태로 개발을 진행한 상태라서 프로필을 변경할 땐 두 테이블 다 데이터를 업데이트해줘야했다. 

 useEffect(() => {
    const fetchData = async () => {
      const userData = await getUser();
      setProfileUrl(userData.user_metadata.imageSrc);
      setUser(userData);
      setNickname(userData.user_metadata.nickname);

      if (!userData) {
        console.error('유저 정보를 가져올 수 없습니다.');
        return;
      }
      const { data: memberData, error: memberError } = await supabase
        .from('member')
        .select('*')
        .eq('user_id', userData.email);

      if (memberError) {
        console.error('회원정보를 가져오지 못했습니다.', memberError);
        return;
      }
    };
    fetchData();
  }, []);

 

 

 

 

프로필 수정하기

 

변경해야할 닉네임은 useRef로 처리해서 DOM에 접근할 수 있도록 했다. state로 처리 하기엔 인풋에 값을 변경할때마다 불필요한 렌더링이 일어나기 때문에 useRef로 처리하는게 좋겠다고 생각했다.

  useEffect(() => {
    const fetchData = async () => {
      const userData = await getUser();
      if (userData) {
        setUser(userData);
        setProfileImg(userData.user_metadata.imageSrc);
        nicknameRef.current ? (nicknameRef.current.value = userData.user_metadata.nickname) : '';
      } else {
        console.error('회원정보를 불러오지 못했습니다.', error);
      }
    };
    fetchData();
  }, []);

 

 

 

 

프로필 업데이트

const handleUpdateData = async (e) => {
    e.preventDefault();
    try {
      const newNickname = nicknameRef.current.value;
      const image = e.target.image.files[0];
      const userData = await getUser();
      const ImageData = await apiImg(image);

      if (!ImageData) {
        throw new Error('이미지 업로드 실패');
      }

      // auth 업데이트
      const { data: authData, error: AuthError } = await supabase.auth.updateUser({
        data: { nickname: newNickname, imageSrc: ImageData }
      });

      if (AuthError) {
        console.error('Auth 업데이트 실패', AuthError.message);
        return;
      }

      console.log('Auth 업데이트 성공', authData);
      setUser(authData);

      // member 테이블 업데이트
      const { data, error } = await supabase
        .from('member')
        .update({ user_name: newNickname, user_imageSrc: ImageData })
        .eq('user_id', userData.email)
        .select('*');

      if (error) {
        console.error('member 업데이트 실패', error.message);
        return;
      }

      console.log('member 업데이트 성공', data);
      navigate(-1);
    } catch (error) {
      console.error('업데이트 실패', error);
    }
  };

 

+ Recent posts