Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4주차/기본/공유과제] #5

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open

[4주차/기본/공유과제] #5

wants to merge 28 commits into from

Conversation

yarimu
Copy link
Contributor

@yarimu yarimu commented May 10, 2024

✨ 구현 기능 명세

  • 기본 과제

🧩 기본 과제

  1. 메인 페이지
  • [✔️ ] 메인 이미지 or 비디오 넣기
  • [✔️ ] 내정보페이지와 회원가입 페이지로 이동할 수 있는 버튼 구현
  1. 로그인 페이지

    • [ ✔️] 아이디와 비밀번호를 입력할 수 있는 input구현
    • [ ✔️] Login page 이미지 넣기
    • [✔️ ] 로그인 버튼(기능)과 회원가입 페이지 이동 버튼 구현
    • [ ✔️] 로그인 실패시 해당 에러메세지를 alert로 띄어주기
    • [ ✔️] useParam 활용해서 id값 보유하고 있기.
  2. 회원가입 페이지

    • [ ✔️] 아이디, 패스워드, 닉네임, 핸드폰 번호를 입력 받는 페이지 구현
    • [ ✔️] 회원가입 버튼 클릭시 post api 통신을 진행하고 성공시 회원가입이 완료되었다는 메시지를 보여주는 alert 띄워준 후, 로그인 메인페이지로 이동
    • [✔️ ] 아이디 중복, 비밀번호 형식 오류, 전화번호 형식 오류 등 모든 에러 alert로 메세지 보여주기
    • [ ✔️] 비밀번호와 전화번호 형식은 input 아래에 보여주기
  3. 마이페이지

    • [✔️ ] get 메소드를 사용해 사용자 정보를 가져오기
    • [✔️ ] 서버에서 받아온 ID, 닉네임, 전화번호 데이터를 렌더링
    • [ ✔️] 비밀번호 변경 토글을 사용해 비밀번호 변경 폼을 on/off할 수 있도록 구현
    • [✔️ ] 기존 비밀번호 입력, 새로운 비밀번호 입력, 새로운 비밀번호 확인 input 구현
    • [✔️ ] input이 비어있을 경우 api 작동되지 않도록 구현
    • [✔️ ] 에러 발생시 api error객체 안 error message를 사용해 alert 띄우기
    • [ ✔️] 홈 이동 버튼 구현
  • 심화 과제
  • 공유 과제(링크)
  • [✔️ ] prettier, eslint, styleLint에 대해
  • lighthouse에 대해

https://forweber.palms.blog/nowsopt-setting-yerim

📌 내가 새로 알게 된 부분

1️⃣ 라우터 사용하기

2️⃣ 라우터 버튼에 적용하기 #Link

3️⃣ 파일분리(하고보니 라우터 이용해야해서 당연했던건가..?)

4️⃣ navigate 쓰는법

5️⃣ 환경변수를 건들면 터미널 껐다가 다시 켜야함

6️⃣ error 메세지 클라이언트에서 모든 것을 해줄 필요는 없다.(서버와의 소통 필요성)

7️⃣ api 명세서의 키값은 일치해야한다.

8️⃣ .env

9️⃣ 에러 언노운 해결

if (error instanceof AxiosError) {
        alert(error.response?.data.message);
      }

🔟 details 태그

1️⃣1️⃣ 어떻게 api 작동을 멈추게 하지? -> api 작동하기 전위치에 if 문을 위치시켜 거르기!!


💎 구현과정에서의 고민과정(어려웠던 부분) 공유!

많은 부분이 어려웠지만, 많은 분들의 도움을 통해 문제해결을 했던 과제였습니다.
구현과정에서의 어려웠던 부분은 새로 알게 된 부분과 동일하다고 보셔도 무방합니다.

마지막으로 마감시간을 지키기 위해 아무런 스타일을 주지 못했지만, 리팩토링 과정을 거치며 이 점 수정해보고자 합니다.

🥺 소요 시간

  • 13h

🌈 구현 결과물

구현상세 순서대로입니다!

1.mov
2.mp4
4.mp4
5.mp4

Copy link
Member

@suwonthugger suwonthugger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

당신이 바로 성장형 괴물 ...? 정말 굿입니다! 페이지별로 분리를 너무 잘하셨어요! 이제 페이지에서 복잡한 요소, 중복되는 요소를 컴포넌트로 분리해보면 좋을것 같아요 너무 고생많으셨습니다~

Comment on lines +9 to +16
<BrowserRouter>
<Routes>
<Route path="/login" element={<Login />}></Route>
<Route path="/join" element={<Join />}></Route>
<Route path="/main" element={<Main />}></Route>
<Route path="/my/:memberId" element={<My />}></Route>
</Routes>
</BrowserRouter>
Copy link
Member

@suwonthugger suwonthugger May 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 마이갓... 완벽한 라우팅 최고입니다, 다음에는 path='/'일 때, 그리고 라우팅이 없는 url로 접속했을 때에는 어떤 화면을 보여줄지에 대한것도 생각해보시면 좋을것 같아요!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 이번에는 라우팅이 없는 url은 신경쓰지 않았는데 확실히 신경쓰는게 좋을 것 같아요! 좋은 제안 감사합니다

const submitForm = async () => {
try {
const postJoinData = await axios.post(
`${import.meta.env.VITE_APP_BASE_URL}/member/join`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow... env 사용을 자유자재로 하시는군요... api 주소같이 외부로 노출되면 안되는 부분을 .evn를 사용해서 처리하신게 너무 좋네요~ 다음 프로젝트하실 때도 이런 습관을 들이면 좋을것 같아요

alert("웰컴!");
navigate("/login");
} catch (error) {
if (error instanceof AxiosError) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 마이 굿니스... 에러가 AxiosError객체의 인스턴스인것을 명시해줌으로서 타입에러를 해결하셨군요.. 최고입니다

Comment on lines +41 to +48
<p>아이디</p>
<div>
<input
type="text"
value={userId}
onChange={(e) => setUserId(e.target.value)}
/>
</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 반복되는 부분은 따로 컴포넌트로 분리하여서 사용해도 좋을것 같아요~~
예시를 보여드리자면

Suggested change
<p>아이디</p>
<div>
<input
type="text"
value={userId}
onChange={(e) => setUserId(e.target.value)}
/>
</div>
function YerimInput({title,value,onChange}) {
return (
<>
<p>{title}<p>
<div>
<input
type="text"
value = {value}
onChange={onChange}
/>
</div>
</>
}

Comment on lines +14 to +33
const handleClickLogin = async () => {
try {
const postData = await axios.post(
`${import.meta.env.VITE_APP_BASE_URL}/member/login`,
{
authenticationId: userId,
password: userPw,
}
);
const memberId = postData.headers.location;
navigate(`/my/${memberId}`);

setUniqueId(uniqueId);
// console.log(postData);
// console.log(memberId);
} catch (error) {
alert("아이디,비밀번호를 입력하세요");
console.log(error);
}
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로그인 로직 너무 깔끔하고 좋은데요~~ axios를 잘 사용하시는걸로 봐서 다음에는 axios instance를 활용해보는것도 좋은 경험이 될 것 같아요! 합세 때 해봅시다!!

Comment on lines +10 to +12
<Link to="/my/:memberId">
<button type="button">내정보</button>
</Link>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 useNavigate를 사용했는데, Link를 사용하셨군요! 이 부분에서는 클릭했을 때 아무런 조건없이 해당 url로 이동해야하니 적절한 사용이되겠네요 하나 배워갑니다

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 link를 사용할 생각은 못했는데 배워갑니다!

Comment on lines +21 to +24
console.log(userInfoData);

setUserInfo(userInfoData);
console.log({ userInfo });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

개발 끝나고 안쓰는 console.log들은 지워주기! 실제 프로젝트를 할 때 콘솔에 사용자 정보가 노출되면 좋지 않을 수 있어요

Comment on lines +62 to +66
<UserText>id:{userInfo.data.data.authenticationId}</UserText>

<UserText>닉네임:{userInfo.data.data.nickname}</UserText>

<UserText>전화번호:{userInfo.data.data.phone}</UserText>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 해당 값들을 보여줄 때 변수로 빼서 보여주는 방법도 추천드릴게요~ 가독성이 측면에서 좋아질 수 있어요
구조분해할당 개념에 대해서 가져가셔도 좋을것 같아요~

Suggested change
<UserText>id:{userInfo.data.data.authenticationId}</UserText>
<UserText>닉네임:{userInfo.data.data.nickname}</UserText>
<UserText>전화번호:{userInfo.data.data.phone}</UserText>
const { authenticationId, nickname, phone } = userInfo.data.data
...
return(
<>
<MyWrapper>
<MyContainer>
<UserText>id:{authenticationId}</UserText>
<UserText>닉네임:{nickname}</UserText>
<UserText>전화번호:{phone}</UserText>

Comment on lines +69 to +76
<ul>
<li>현재 비밀번호</li>
<input
type="text"
value={previousPassword}
onChange={(e) => setPreviousPassword(e.target.value)}
required
/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<ul> 태그를 사용하고 안의 요소가 list의 item인것을 보여주기 위해서는 다음과 같은 형식을 사용하는것을 추천드릴게요!

Suggested change
<ul>
<li>현재 비밀번호</li>
<input
type="text"
value={previousPassword}
onChange={(e) => setPreviousPassword(e.target.value)}
required
/>
<ul>
<li>
<h3> 현재 비밀번호 </h3>
<input
type="text"
value={previousPassword}
onChange={(e) => setPreviousPassword(e.target.value)}
required
/>
</li>
</ul>

Comment on lines +41 to +48
<p>아이디</p>
<div>
<input
type="text"
value={userId}
onChange={(e) => setUserId(e.target.value)}
/>
</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요기도 이전에 언급한 부분이랑 형식이 동일하게 반복되는데 컴포넌트 폴더를 하나 만들어서 분리해두면 좋을것 같아유

Copy link

@seong-hui seong-hui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

과제 내용에 대해서 빠짐없이 너무 구현을 잘해주셨습니다. 변수명도 알아보기 쉽게 잘 써주셔서 어느 동작을 하는 지 잘 이해할 수 있었어요! 공통적으로 사용하는 것은 컴포넌트로 만들어서 반복적으로 사용해보기라는 챌린지를 합세때 잘해봅시다!! 조금씩 다른 곳에서 공통적으로 사용하기 위해서는 컴포넌트에 어떤 항목들이 props로 받아야하는지에 대해서도 생각해보는 것도 좋은 공부가 될 것 같아요. 과제 너무 잘 하셔서 배우고 갑니다. 합세도 화이팅!!

Comment on lines +9 to +16
<BrowserRouter>
<Routes>
<Route path="/login" element={<Login />}></Route>
<Route path="/join" element={<Join />}></Route>
<Route path="/main" element={<Main />}></Route>
<Route path="/my/:memberId" element={<My />}></Route>
</Routes>
</BrowserRouter>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 이번에는 라우팅이 없는 url은 신경쓰지 않았는데 확실히 신경쓰는게 좋을 것 같아요! 좋은 제안 감사합니다

phone: userPhoneNumber,
}
);
console.log(postJoinData);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

개발중에 확인을 위해서 사용한 console.log() 성능이나 보안적인 측면에서 지워주는게 좋다고 해요! 다음에는 확인후에 지워서 git에 올리는 걸 추천해드립니다!

navigate("/login");
} catch (error) {
if (error instanceof AxiosError) {
alert(error.response?.data.message);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error.response가 있을 때만 메세지를 출력하게 하셨군요 저는 if문에서 따로 확인을 했었는데 이렇게 alet에서 확인하는 것도 좋은 방법같네요 배워갑니당!

/>
</div>

<button type="button" onClick={handleClickLogin}>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

버튼도 반복해서 사용한다면 버튼 컴포넌트를 만들어서 이를 사용하는 것도 추천해드립니다!

Comment on lines +10 to +12
<Link to="/my/:memberId">
<button type="button">내정보</button>
</Link>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 link를 사용할 생각은 못했는데 배워갑니다!

display: flex;
justify-content: center;
align-items: center;
background-color: #f5dad2;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

theme를 적용해서 반복적으로 사용하는 테마 컬러를 theme로부터 불러와서 사용해보는 방법도 좋을 거 같아요! 나중에 background색상이 변경되면 theme안에 있는 색상만 변경하면 모든 컬러가 변경되니 더 편리할 거예요!

Copy link

@cindy-chaewon cindy-chaewon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드 넘 깔끔하게 작성하신거 같아요!! 과제하느라 수고하셨습니다! 합세 파이팅!!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 파일은 지워도 될 거 같아요..!!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public 폴더 안에 img 폴더 가 있는거 같은데, 이 폴더를 assets에 옮기면 좋을 거 같아요!

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="ko">

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ko로 바꿔주는 꼼꼼함 굳굳!!

Comment on lines +79 to +81
<button type="button" onClick={submitForm}>
회원가입
</button>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

버튼 부분도 반복되고 있으니 공통 컴포넌트로 분리해서 적용하면 좋을 거 같아요!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants