-
Notifications
You must be signed in to change notification settings - Fork 1
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주차 기본/심화/공유과제 ] 로그인, 회원가입 페이지 #6
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이슈까지 파서 작업을 하셨군요, 좋네요. 코드도 깔끔하게 잘 작성하신 것 같습니다.
api 분리도 잘되어있고, 페이지 안에 로직, 구조, 스타일도 위치에 맞게 딱 분리되어 있어서 읽기도 편했던 것 같습니다.
4주차 과제 고생 많으셨습니다. 많이 배워갑니다~! 👍
week4/index.html
Outdated
@@ -0,0 +1,18 @@ | |||
<!doctype html> | |||
<html lang="en"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ko
드리뷰 시작하겠습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p3) en대신 ko사용하시는게 좋을 거 같아여
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ㅋㅋㅋ 감사합니다 반영완료했습니다!
week4/src/main.tsx
Outdated
import { theme } from './styles/theme.ts'; | ||
|
||
ReactDOM.createRoot(document.getElementById('root')!).render( | ||
<> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p4: ThemeProvider로 감싸져 있어서, <></>는 굳이 필요없어 보입니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영 완료 했습니다!
${reset} | ||
|
||
html, | ||
body, | ||
div, | ||
span, | ||
applet, | ||
object, | ||
iframe, | ||
h1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5: 혹시 라이브러리를 통한 ${reset}과 css 코드로 reset하는 부분이 둘다 있는 이유가 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
흠,,, 이 부분도 생각해보니 reset 을 했으니 굳이 하는 이유가 없겠군요! 기존의 css코드로 reset하는 부분은 제가 기존에 사용하는 코드를 가져왔습니다!
week4/src/pages/home/Home.tsx
Outdated
const [onIdError, setIdError] = useState({ | ||
open: false, | ||
message: 'id를 입력해주세요', | ||
}); | ||
const [onPwError, setPwError] = useState({ | ||
open: false, | ||
message: 'password를 입력해주세요', | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5: [onIdError, setOnIdError]가 아니고 state 변수 이름에만 on을 붙이는 이유가 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
어라라 그렇네요 저도 궁금해요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그러게요..? 제 왜인지 모르겠는데 이게 토글 로직이랑 헷갈렸던 것 같아요!
제가 on이라는 접두사는 보통 토글 상태에 사용하는데,,,
수정했습니다!
password, | ||
}; | ||
|
||
const { data, location } = (await login(loginInfo))!; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5: 잘 몰라서 그런데, api의 login 함수에서도 요청하는 부분에 await이 되어있는데, 이 함수를 호출할 떄도 await을 해줘야 하는건가요..?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
하하 어제 얘기했던거처럼 있는게 맞네요,,, 하나 배워갑니다 ㅎㅎ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네! async로 작성한 함수는 promise를 반환하기 때문에 await 으로 받아야합니다!
week4/src/pages/signup/Signup.tsx
Outdated
<Form onSubmit={handleSubmit}> | ||
<div> | ||
<Title>회원가입</Title> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5: 저 별 생각없이 form 태그 안쓰고, input이랑 button 만 가지고 구현했는데,,, form 태그 좋네요 ㅎㅎ
<Button type="submit">회원가입</Button> | ||
<Button type="button" onClick={() => navigate(-1)}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5: Button에 따라서 type도 다 다르게 준 디테일 좋네요 👍👍
padding: 4rem 6rem; | ||
|
||
color: white; | ||
|
||
background-color: green; | ||
border: 1px solid #ccc; | ||
border-radius: 10px; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5: rem와 px을 둘다 사용하시는 것 같은데 각각을 쓰는 기준이 있으신가요? border에는 px을 쓰시는 건가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
border-radius나 border 같은 부분은 10px 미만으로 주로 사용되어서 rem으로 적으면 0.1rem 이런 식으로 적게되서 직관적이지 못하더라고요!
그런 로직들은 px로 사용하고 있습니다!
week4/src/pages/mypage/Mypage.tsx
Outdated
const fetchData = async () => { | ||
if (id) { | ||
const response = await getUser(id); | ||
|
||
setUserInfo(response.data); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5: 함수 선언은 useEffect 밖에 하는 것이 더 낫지 않을까요? 이 안에서만 사용하는 함수라 일부로 안에서 선언하신건가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
흠,,, 그러게요 useEffect 안에서만 사용되면 괜찮을 것 같은데! 다른 부분에서도 사용되면 빼도 괜찮을 것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
일단 저도 빼는 걸로 반영했습니다!
|
||
<Box> | ||
<ToggleButton onClick={() => setShowPasswordChange(!showPasswordChange)}> | ||
비밀번호 변경 {showPasswordChange ? '⇧' : '⇩'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5: 우와 화살표 방향까지 !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4주차 과제 넘 수고하셨어요
코드리뷰하는 내내 코드가 넘 깔끔하고 잘 읽혀서 배울 점이 많았네요😄
합세 때도 파이팅 입니다~~!
week4/index.html
Outdated
as="style" | ||
crossorigin | ||
href="https://cdn.jsdelivr.net/gh/orioncactus/[email protected]/dist/web/variable/pretendardvariable.css" /> | ||
<title>Vite + React + TS</title> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5: 여기 title도 적절하게 바꿔줘도 좋을 것 같아요 (사실 저도 자주 깜빡하는 부분이긴 합니다 😶🌫️ )
<title> 도영이의 행복한 로그인 <title>
이라던지... ㅎㅎ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
맞네요 ㅎㅎ
감사합니다! 반영 완료했습니다
week4/src/Router.tsx
Outdated
<BrowserRouter> | ||
<Routes> | ||
{routerData.map((data, i) => ( | ||
<Route key={`route-${i}`} path={data.path} element={data.element} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5: 이렇게 path, element를 따로 빼서 활용하는 방법을 보니까 생각났는데 map을 사용하지 않고 더 간결하게 구현할 수 있는 방법도 있더라구요
참고하셔도 좋을 것 같아서 링크 남깁니다~!
https://medium.com/@duchanjo/react-router-routerprovider-ee36a0dfd6fc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
감사합니다!
반영 완료 했습니다!
@@ -0,0 +1,94 @@ | |||
import axios, { isAxiosError } from 'axios'; | |||
|
|||
const API_URL = `${import.meta.env.VITE_BASE_URL}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5: env파일로 숨겨 놓기.. 아주 좋네요 👍
week4/src/pages/home/Home.tsx
Outdated
const [onIdError, setIdError] = useState({ | ||
open: false, | ||
message: 'id를 입력해주세요', | ||
}); | ||
const [onPwError, setPwError] = useState({ | ||
open: false, | ||
message: 'password를 입력해주세요', | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
어라라 그렇네요 저도 궁금해요
`; | ||
|
||
const Img = styled.img` | ||
width: ${(props) => props.width}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5: 달라지는 속성을 props로 받아서 재사용성을 높이는 방법 👍 좋네요
좋은 정보 하나 배워갑니다~!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 아직 컴포넌트로 분리하지는 않았지만, 이 부분을 컴포넌트로 분리하면 더 좋을 것 같네요 ㅎㅎ
week4/index.html
Outdated
@@ -0,0 +1,18 @@ | |||
<!doctype html> | |||
<html lang="en"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p4) en 대신 ko로 작성하시는게 좋을 것 같아염~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵! 반영 완료했습니다!
import styled from '@emotion/styled'; | ||
|
||
import Router from './Router'; | ||
|
||
function App() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p4) emotion을 사용했군여~ 저도 한번 참고해서 배워가겠습니다~~
week4/src/Router.tsx
Outdated
const Router = () => { | ||
const routerData = [ | ||
{ | ||
path: '/', | ||
element: <Home />, | ||
}, | ||
{ | ||
path: '/:id', | ||
element: <Main />, | ||
}, | ||
{ | ||
path: '/signup', | ||
element: <Signup />, | ||
}, | ||
{ | ||
path: '/mypage/:id', | ||
element: <Mypage />, | ||
}, | ||
]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5) router Data안에 이렇게 경로와 요소를 넣을 수도 있군여
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
맞아요~
react router v6 부터 아래 링크와 같이 createRouter를 사용하는 방식을 권장하고 있습니다!
참고하면 좋을 것 같아요!
https://reactrouter.com/en/main/routers/create-browser-router#createbrowserrouter
export const login = async (loginInfo: LoginInfo) => { | ||
try { | ||
const response = await axios.post(`${API_URL}/member/login`, { | ||
authenticationId: loginInfo.id, | ||
password: loginInfo.password, | ||
}); | ||
|
||
return { data: response.data, location: response.headers.location }; | ||
} catch (error) { | ||
if (isAxiosError(error)) { | ||
alert(error.response?.data.message); | ||
} | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5)저는 이번에 axios대신에 fetch를 사용했는데여~~찾아보니 axios를 사용하면 형변환을 할 필요가 없다고 하더라구여?! 확실히 도영님 코드 보니까 간결한 느낌이 확 드네여
if (!id) { | ||
setIdError((prev) => { | ||
return { ...prev, open: true }; | ||
}); | ||
|
||
setTimeout(() => { | ||
setIdError((prev) => { | ||
return { ...prev, open: false }; | ||
}); | ||
}, 2000); | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p4) 혹시 이부분 코드설명가능할까여?!
이전 상태값을 활용하여 입력된 ID 값의 유효성을 검사하고, ID가 존재하지 않을 때 오류 메시지를 관리하는 로직을 보여주는 코드인것 같은데 맞을까여?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
맞아요! 이 부분은 입력된 아이디가 없을 때, 오류 메세지를 보여주고, setTimeout 함수를 사용해서 2초 뒤에 에러 메시지가 사라지게 구현했습니다!
const Input = styled.input` | ||
width: 20rem; | ||
padding: 1rem; | ||
|
||
border: 1px solid #ccc; | ||
border-radius: 5px; | ||
`; | ||
|
||
const Error = styled.p` | ||
position: absolute; | ||
bottom: -1.5rem; | ||
|
||
color: red; | ||
font-size: 1.2rem; | ||
`; | ||
|
||
const Button = styled.button` | ||
padding: 1rem; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5) px대신 rem사용 굿입니당
import { SignUpInfo, signUp } from '../../api'; | ||
import { formatPhoneNumber, validatePassword } from '../../utils'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p4) 이번 합세 때 path alias관련해서 새롭게 알게 되었는데 담에 한번 적용해보시는 것도 좋을 거같아염
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
감사합니다!
이번 합세에도 적용했으니 잘 사용해보면 좋을 것 같아요!
✒️ 관련 이슈번호
🧩 기본 과제
메인 페이지
로그인 페이지
회원가입 페이지
마이페이지
🔥 심화 과제
메인페이지
로그인 페이지
회원가입 페이지
input이 비어있는 상태로 api연결 시도했을시
해당 input 테두리 색상 변경
input에 focus 맞추기
api요청 금지
전화번호 양식 정규표현식으로 자동입력되도록 설정 (숫자만 입력해도 "-"가 붙도록)
비밀번호 검증 유틸 함수 구현 (검증 통과되지 않을시 api요청 금지)
공유과제
링크 첨부(팀 블로그 링크) : https://forweber.palms.blog/now-sopt-settings-doyeong
📌 내가 새로 알게 된 부분
emotion에 ts를 처음 사용해봐서, props에 해당하는 타입을 주는 방법을 알게 되었습니다!
동영상 넣는 방법을 알 수 있었습니다!
아래와 같이 video 태그를 사용해서 넣어주었습니다!
ts에서 axios 요청을 보내고 응답을 받을 때, error 객체의 타입을 아래와 같이 설정해서 처리할 수 있습니다.
💎 구현과정에서의 고민과정(어려웠던 부분) 공유!
StyleLint를 적용했는데, styled를 import 과정에서 아래와 같이 macro가 계속 붙습니다...
import styled from '@emotion/styled/macro';
혹시 해결하는 법 아시는 분 공유 부탁드립니다!
🥺 소요 시간
15h
🌈 구현 결과물
영상
https://silk-title-f5a.notion.site/4-7c971fc1eceb4d6aa4fcda07b4a873f5?pvs=4