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주차 기본/심화/공유 과제] 로그인, 회원가입 구현해보기 #4

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

Conversation

ocahs9
Copy link
Contributor

@ocahs9 ocahs9 commented May 10, 2024

✨ 구현 기능 명세

🧩 기본 과제

  1. 메인 페이지

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

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

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

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

🔥 심화 과제

  1. 메인페이지

    • 비디오에 여러 기능을 적용
  2. 로그인 페이지

    • input이 비어있을 경우 api요청 보내지 않고 아래 error message를 띄워주기
  3. 회원가입 페이지
    input이 비어있는 상태로 api연결 시도했을시

    • 해당 input 테두리 색상 변경

    • input에 focus 맞추기

    • api요청 금지

    • 전화번호 양식 정규표현식으로 자동입력되도록 설정 (숫자만 입력해도 "-"가 붙도록)

    • 비밀번호 검증 유틸 함수 구현 (검증 통과되지 않을시 api요청 금지)

공유과제

  • prettier, eslint, styleLint에 대해
  • lighthouse에 대해

링크 첨부(팀 블로그 링크) :
https://forweber.palms.blog/initialsettings-junhyuk


📌 내가 새로 알게 된 부분

  • ~ 부분 이렇게 구현했어요, 피드백 부탁해요!
    타스를 새롭게 알게 되었습니다.. 물론 아직 익숙하진 않지만..
    타스 말고도 초기세팅에 대해 대략은 알게 되었습니다.

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

  • ~ 부분이 잘 구현한건지 잘 모르겠어요!
  • ~부분 다른 방법이 있는지 궁금해요!
  • 타스로 하니까 에러가 너무 많이 나요 ㅜㅜ 그냥 전체적으로 문제라서 오히려 질문할 게 없습니다..

🥺 소요 시간

  • 17h

🌈 구현 결과물

링크 올려두겠습니다 !
https://www.youtube.com/watch?v=-9nHhr8k20w
https://www.youtube.com/watch?v=Y79Fy645o20

Copy link

@thisishwarang thisishwarang left a comment

Choose a reason for hiding this comment

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

저도 이번과제를 하며 타스를 처음 공부해보는데 참 어려운게 많은것 같아요.. 그래도 코드에 최대한 배운것들을 녹여내기 위해 노력한 모습들이 보여 대단한것 같습니다. 이번 공유과제인 초기세팅에도 정말 진심을 다해 공부하시는 모습이 인상깊었습니다. 고생하셨어요!!



interface InfoProps{
//만들면서 필요한 것 작성해나갈 예정

Choose a reason for hiding this comment

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

이런 주석들은 pr전에는 삭제하는게 좋을것 같아요!

content: any;
}

function Info({name, content}: InfoProps) : JSX.Element

Choose a reason for hiding this comment

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

우선 JSX.Element 를 children prop을 사용하기 위해 지정해두신것 같은데 저도 타스가 처음이라 잘은 모르지만
보통 ReactNode를 사용한다고 합니다. 링크 걸어둘테니 한번 읽어보면 좋을 것 같아요!

children prop 타입 지정

`;


export default Info;

Choose a reason for hiding this comment

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

해당 컴포넌트는 스타일 속성과 관련된 부분인것 같은데 그럼 assets 폴더 말고 styles 폴더를 생성해서 넣는것이 어떨까요??
assets 폴더에는 png, mp4, svg 와 같은 파일들이 들어오는 폴더라고 알고 있습니다!

Choose a reason for hiding this comment

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

동의합니다! styles 폴더도 좋지만 commons 폴더로 분리하여 공통으로 쓰이는 파일로 둬도 좋을 것 같습니다!
그리고 FlexBox라는 이름보다는 InfoWrapper, InfoBox와 같이 의도를 드러내는 게 코드의 가독성 측면에서 더 좋을 것 같다고 생각해요. 어떻게 생각하시는지 궁금합니다!

console.log(1);
if(isEmptyId === true){
alert("id 입력하세요.");
idInput.current.focus(); //idInput.current는 undefined일 수 있습니다..?

Choose a reason for hiding this comment

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

useRef 훅을 사용하면 종종 undefined로 인식하는 오류가 있는것 같더라구요. 자세한 에러내용은 모르지만 아래 링크 참고해보시면 좋을 것 같습니다.

링크

Choose a reason for hiding this comment

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

저도 간혹가다 undefined일 수 있다는 에러 메시지를 마주하곤 하는데 그럴 때마다 옵셔널 체이닝 문자나 &&연산자를 주로 사용하는 편입니다!
옵셔널 체이닝 관련 문서 첨부할게요~

<SignUpWrapper>
<LoginHeader>
<h1>Login</h1>
<FontAwesomeIcon icon={faRightToBracket} fontSize={`4rem`} fade/> {/*individual import를 잘 살피기! 추가로 공식 문서 잘 읽기) https://docs.fontawesome.com/web/style/size */}

Choose a reason for hiding this comment

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

저도 fontawesome에서 아이콘 쓰려고 했다가 에러나서 시간 관계상 그냥 다른 아이콘 사용했는데 성공하셨군요? 공식 문서엔 항상 답이 있는것 같습니다..ㅎ


function handleChangeIdInput(e: React.ChangeEvent<HTMLInputElement>)
{
setUserId((prev)=>e.target.value);

Choose a reason for hiding this comment

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

(prev) 를 사용하는 이유는 보통 set함수로 값을 변경할 때 이전 값을 기준으로 변경시킬 때 사용하는것으로 알고 있습니다.
현재 코드에서는 prev가 사용되고 있지 않기 때문에 setUserId(e.target.value) 로 수정해도 될 것 같아요!

Comment on lines +16 to +19
function handleClickMyPageBtn()
{
navigate(`/mypage/${memberId}`);
}

Choose a reason for hiding this comment

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

mypage로 라우팅 하는 해당 함수와 비슷하게 홈으로, 회원가입 페이지로 이동시키는 버튼들이 이번 과제에 있었는데 이 모든 버튼이 이동되는 경로, 버튼 text만 다르고 기능이나 디자인이 같아서 공통 컴포넌트로 빼보면 좋을 것 같아요

<>
<MainPage>
<StyledTitle>메인페이지</StyledTitle>
<video width="500" height="400" autoPlay loop muted> {/*왜 크기가 내가 원하는대로 설정이 안되지? %도 그렇고.. vw도 그렇고.. */}

Choose a reason for hiding this comment

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

React-player 라는 라이브러리가 있는데 한번 사용해보면 좋을 것 같아요!

Choose a reason for hiding this comment

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

저도 이번에 동영상 넣는 방법에 대해 알아보다가 React-player라는 라이브러리를 발견해서 써봤는데 다양하게 커스텀 할 수 있어서 괜찮더라고요...!
video 태그 사용해서 구현하는 방법도 덕분에 알아갑니다👍

useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get("http://34.64.233.12:8080/member/info", {

Choose a reason for hiding this comment

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

http://34.64.233.12:8080 과 같은 url 정보는 .env 혹은 .env.local 파일을 생성해서 VITE_APP_BASE_URL 이름으로 상수화 시키고, 필요한 부분에서 ${import.meta.env.VITE_APP_BASE_URL}/member/info 이런식으로 사용하면 더 좋을 것 같습니다.


);
}

Choose a reason for hiding this comment

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

하나의 페이지 컴포넌트에서 비즈니스 로직을 담당하는 코드들과 UI를 담당하는 코드들이 다같이 있어서 한 파일에 코드가 굉장히 길어지고 가독성이 떨어질 수 있어요. 우선 styled-components를 사용해서 UI를 담당하는 컴포넌트를 생성하는 부분을 따로 빼면 좋을 것 같습니다. 예를들어 해당 SignUp.tsx 파일도 pages 폴더 아래에 SignUp폴더를 생성하여 그 내부에 SignUp.tsx, SignUp.styled.ts 두개로 나눌 수 있겠죠?
이후 SignUp.styled.ts 파일에서 export한 컴포넌트들을 SignUp.tsx 파일에서
import * as S from "./SignUp.styled"; 이런식으로 import 해와서 컴포넌트 호출할 때 <S.ComponantName> 으로 작성하면 어떤 컴포넌트가 UI관련 컴포넌트이고, 어떤게 로직관련 컴포넌트인지 구별이 쉬워질 것 같아요. 한 파일의 코드량도 줄일 수 있을 것 같습니다.

Copy link

@namdaeun namdaeun left a comment

Choose a reason for hiding this comment

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

과제 고생많으셨습니다! 타스 처음 써보시는 건데도 인터페이스도 잘 쓰시고 타입도 잘 명시되어 있어서 감탄하면서 코리했습니다 !! 전체적으로 스타일 컴포넌트 네이밍만 조금 더 신경 써보시면 코드 가독성이 더더 좋아질 것 같다고 생각해요! 합세도 화이팅해봅시다아🔥

`;


export default Info;

Choose a reason for hiding this comment

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

동의합니다! styles 폴더도 좋지만 commons 폴더로 분리하여 공통으로 쓰이는 파일로 둬도 좋을 것 같습니다!
그리고 FlexBox라는 이름보다는 InfoWrapper, InfoBox와 같이 의도를 드러내는 게 코드의 가독성 측면에서 더 좋을 것 같다고 생각해요. 어떻게 생각하시는지 궁금합니다!

Choose a reason for hiding this comment

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

요 파일도 마찬가지로 공통 컴포넌트로 분리하면 좋을 것 같네요~!

console.log(1);
if(isEmptyId === true){
alert("id 입력하세요.");
idInput.current.focus(); //idInput.current는 undefined일 수 있습니다..?

Choose a reason for hiding this comment

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

저도 간혹가다 undefined일 수 있다는 에러 메시지를 마주하곤 하는데 그럴 때마다 옵셔널 체이닝 문자나 &&연산자를 주로 사용하는 편입니다!
옵셔널 체이닝 관련 문서 첨부할게요~

Comment on lines +33 to +34
//idInputText.current.innerText = "아이디를 입력하세요.";
//pwInputText.current.innerText = "";

Choose a reason for hiding this comment

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

안 쓰이는 코드는 삭제해주면 좋을 것 같습니다!
(Chore 커밋 컨벤션을 요럴 때 보통 사용합니다)




function handleSubmitForm(e:React.FormEvent) //제출을 할 시, API 요청으로 정보 입력하고 받아오는 과정

Choose a reason for hiding this comment

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

이벤트에 대한 타입도 달아주셨군요 타스 넘 잘 쓰시는데요?? 굿굿👍

Comment on lines +61 to +68
if(password.length < 8 || !password.match(/\d/) || !password.match(/[^a-zA-Z\d]/) || !password.match(/[a-z]/) && !password.match(/[A-Z]/) )
{
return false;
}
else
{
return true;
}

Choose a reason for hiding this comment

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

(password.length < 8 || !password.match(/\d/) || !password.match(/[^a-zA-Z\d]/) || !password.match(/[a-z]/) && !password.match(/[A-Z]/) ) ? false : true
  • 조건이 if문 밖에 없으니까 삼항연산자를 사용해서 줄여볼 수도 있겠네요!

Comment on lines +164 to +165
if(inputPhoneNumber.length <= 11) //11자리 넘어가면 더 작성이 불가능하도록 한번 만들어봤습니다 ㅎㅎ..
{

Choose a reason for hiding this comment

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

좋은 시도네요! 저도 배워갑니다~~


function handleChangePhoneInput(e: React.ChangeEvent<HTMLInputElement>)
{
let inputPhoneNumber = e.target.value.replace(/[^0-9]/g, ''); // 숫자 이외의 문자 제거 (0-9까지의 숫자를 제외한다는 의미, global로 전부 살펴본다는 의미)

Choose a reason for hiding this comment

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

inputPhoneNumber를 const가 아닌 let으로 선언해준 이유가 궁금해요!


`;

const ColFlexDiv = styled.div`

Choose a reason for hiding this comment

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

시맨틱 태그를 잘 활용하면 웹 접근성이 더 좋아질 수 있겠죠??
여기는 재사용되는 부분이니 article 태그를 사용 해볼 수 있겠어요! 그리고 ColFlexDiv라는 이름 대신 InputContainer와 같은 이름으로 바꿔보는 게 코드 가독성 측면에서 더 좋을 것 같다고 생각해요!

}
}

function handleSubmitForm(e:React.FormEvent) //제출을 할 시, API 요청으로 정보 입력하고 받아오는 과정

Choose a reason for hiding this comment

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

API 요청하는 코드를 다른 파일로 분리하면 로직도 분리되고 전체적인 코드가 더 간결해질 수 있겠다고 생각해요! 어떻게 생각하시나요?

Copy link
Contributor

@ljh0608 ljh0608 left a comment

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