-
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주차 기본/공유 과제 ] 보운이의 로그 #5
base: main
Are you sure you want to change the base?
Conversation
@@ -0,0 +1 @@ | |||
export const BASE_URL = 'http://34.64.233.12:8080'; |
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)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.
p1: 서버 주소는 .env 파일로 빼주세요!
import {Area, HelpP, IMG, Input, InputContaier, InputSort, MoveButton} from '../style/styleComponents'; | ||
import loginImg from '../assets/img2.jpg'; | ||
import {Link, useNavigate} from 'react-router-dom'; | ||
import {useState} from 'react'; | ||
import axios from 'axios'; | ||
import {BASE_URL} from '../assets/base-url'; | ||
|
||
export default function LoginPage() { | ||
const navi = useNavigate(); | ||
const [id, setId] = useState(''); | ||
const [pw, setPw] = useState(''); | ||
|
||
const handleLogin = async () => { | ||
if (id && pw) { | ||
//만약 모두가 값이 있다면 | ||
try { | ||
await axios | ||
.post(`${BASE_URL}/member/login`, { | ||
authenticationId: id, | ||
password: pw, | ||
}) |
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)저는 fetch를 사용했는데 axios를 많이들 사용했더라구여?! 사용하는 방법 배워갑니다~ 그리고 확실히 axios를 사용하면 형변환 할일이 없어 코드가 간결해지는 것 같아염
function handleShowPw() { | ||
const nowState = document.getElementById('showornot')!.style.visibility; | ||
if (nowState == 'hidden') { | ||
//숨겨뒀다가 열려고 누름 -> 보여야함 | ||
document.getElementById('showornot')!.style.visibility = 'visible'; | ||
} else { | ||
document.getElementById('showornot')!.style.visibility = 'hidden'; | ||
} | ||
} | ||
|
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) 비밀번호 여닫는 폼을 이렇게도 구현할 수 있군여 배워갑니다.
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: 리액트에서 DOM에 직접접근하여 조작하는 것은 권장되지 않는 방식입니다. state값을 styled 컴포넌트에 인자로 전달에서 인자에 따라 스타일 값을 바꿔주거나, DOM을 직접 조작해야한다면 useRef를 사용하여 조작하는 것이 나을 것 같습니다.
혹시 더 좋은 방법이 있다면 알려주시면 감사하겠습니다.
<InputSort>ID</InputSort> | ||
<div style={{width: '100%'}}> | ||
<Input | ||
onChange={(e) => setId(e.currentTarget.value)} | ||
type="text" | ||
placeholder="아이디를 입력하세요" | ||
/> | ||
{!id && <HelpP>아이디를 입력하세요</HelpP>} |
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) 혹시 div style옆 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.
pr에 작성해주신 고민이 이 부분이네요.
간단한 스타일의 경우 사실 styled component를 추가로 만드는 것이 비효율 적으로 보일 수는 있지만, 나중에 유지보수를 하거나 스타일을 변경해야 하는 상황을 생각해보면, 스타일 코드가 여기저기에 나뉘어져 있다면, 유지보수할 때의 난이도가 굉장히 올라간다고 생각합니다. 따라서 조금 비효율적으로 보일진 몰라도, styled component를 사용하는 프로젝트라면 모든 스타일을 styled로 주는 것이 좋을 것 같습니다.
태그이름은 개인적 규칙이나, 팀의 컨벤션에 맞게 작성하셔야하지만 PR에 물어보셔서 답변해드리자면 InputWrapper등의 이름으로 감싸주면 될 것 같습니다.
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: 저도 위 생각에 동의합니다. 스타일 코드가 이렇게 나뉘어져있으면 유지보수가 힘들어 질 수 있어요!
아래 링크와 같이 본인 스스로의 규칙을 만들면 좋아요! 그리고 그 규칙들을 협업하는 팀원들과 공유한다면 더 좋을 것 같아요!
import {useEffect, useState} from 'react'; | ||
import {Area, Info, MoveButton, OneLine, PwEditBtn, ShowORNot} from '../style/styleComponents'; | ||
import {Link, useParams} from 'react-router-dom'; | ||
import axios from 'axios'; | ||
import {BASE_URL} from '../assets/base-url'; | ||
import PwEditComp from './PwEditComp'; | ||
|
||
type Info = { | ||
id: string; | ||
nickname: string; | ||
phone: string; | ||
}; |
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)코드를 각각 구조에 맞게 잘 나누신 것 같아여
/*useEffect(() => { | ||
//하이픈 추가 | ||
setPhone({}); | ||
}, [phoneRef.current?.value]);*/ | ||
|
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) 주석처리한 코드는 없애시는게 좋을 거 같아여~
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.
전반적으로 코드도 깔끔하게 작성하셨고, styled 컴포넌트를 분리하시려는 노력도 너무 좋은 것 같고, TypeScript도 처음 사용해보신다고 했던 것 같은데, 잘 적용해서 과제 완성해주셔서 너무 고생 많으셨습니다!
또한 고민의 흔적들이나 궁금한점들도 PR과 주석으로 잘 남겨주셔서 리뷰하기 더 편했던 것 같습니다! 과제 정말 고생 많으셨습니다!
<BrowserRouter> | ||
<React.StrictMode> | ||
<App /> | ||
</React.StrictMode> | ||
</BrowserRouter> |
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: 일반적으로 애플리케이션의 모든 부분에 StricMode를 적용하기위해서 StricMode를 가장 바깥쪽으로 빼주는 것으로 알고 있습니다.
BrowserRouter와 React.StrictMode의 위치를 바꿔주는 것이 좋을 것 같습니다.
function MainPage() { | ||
const {memberId} = useParams<string>(); | ||
|
||
console.log(memberId); |
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: 테스트 끝난 console.log는 삭제해주세요~
<div> | ||
<Header>보운이의 로그인</Header> | ||
<Section> | ||
<ReactPlayer url={'/videos/고양이.mp4'} playing={true} loop={true} muted={true} /> |
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: ReactPlayer사용해서 동영상 넣으셨군요 좋네요!
<div> | ||
<Header>보운이의 로그인</Header> | ||
<Section> |
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: 가장 div가 딱히 스타일도 없고, 의미가 없는 태그라면, div대신 <></>로 감싸주는건 어떨까요?
//location Header에 있는 게 이거 맞나..? | ||
//useParam을 어떻게 활용하지....? | ||
const memberId = res.headers.location; | ||
console.log(memberId); | ||
//아 이걸 useParam써서 메인으로 보내자 |
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: ㅋㅋㅋㅋ 생각의 흐름이 주석에 남아있는게 좋네요 ㅋㅋ console 만 지워주시면 좋을 것 같습니다.
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: ㅋㅋㅋㅋ 너무 멋져요
type="password" | ||
placeholder="비밀번호를 입력하세요" | ||
/> | ||
{!pw && <HelpP>비밀번호를 입력해주세요 제발</HelpP>} |
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: pw state값에 따라 메시지 띄워주는거 좋네요!
<Input ref={idRef} id="idInput" type="text" /> | ||
</InputContaier> | ||
<InputContaier> | ||
<InputSort>비밀번호</InputSort> | ||
<div style={{width: '100%'}}> | ||
<Input ref={pwRef} id="pwInput" type="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: pr에 특정한 요소를 가져오기 위해서, 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.
p5: 저도 여기 궁금해요!
function handleShowPw() { | ||
const nowState = document.getElementById('showornot')!.style.visibility; | ||
if (nowState == 'hidden') { | ||
//숨겨뒀다가 열려고 누름 -> 보여야함 | ||
document.getElementById('showornot')!.style.visibility = 'visible'; | ||
} else { | ||
document.getElementById('showornot')!.style.visibility = 'hidden'; | ||
} | ||
} | ||
|
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: 리액트에서 DOM에 직접접근하여 조작하는 것은 권장되지 않는 방식입니다. state값을 styled 컴포넌트에 인자로 전달에서 인자에 따라 스타일 값을 바꿔주거나, DOM을 직접 조작해야한다면 useRef를 사용하여 조작하는 것이 나을 것 같습니다.
혹시 더 좋은 방법이 있다면 알려주시면 감사하겠습니다.
<PwEditBtn onClick={handleShowPw}>{'>'}</PwEditBtn> | ||
</div> | ||
<ShowORNot id="showornot"> | ||
<PwEditComp props={memberId!} /> |
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: 컴포넌트에 전달하는 인자이름을 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.
p5: memberId뒤에 ! 를 붙인 이유가 있으실까요? 에러가 나서 그냥 추가하신 거라면, 사용하는 쪽에서 null 체크를 하는 것으로는 해결이 안되나요?
실제로 url에 id 가 없으면 memberId가 빈 값일 수도 있을 것 같아 여쭤봅니다!
import {BASE_URL} from '../assets/base-url'; | ||
import {Info, Input, MoveButton, OneLine} from '../style/styleComponents'; | ||
|
||
export default function (props: any) { |
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: typescript가 익숙하지 않다고 하셔서 적용한 것 자체가 너무 좋다고 생각하긴합니다.
하지만 제가 조금만 더 욕심내보자면, type에 any를 사용하는 것은 가능한 지양해주시는 것이 좋습니다!
여기서는 type이 string인 props가 들어있는 props객체가 넘어오고 있으므로, { props: string } 로 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.
p4: 그리고 여기 컴포넌트 부분은 pages 폴더가 아니라 따로 분리해주면 좋을 것 같아요!
그리고 네이밍도 const PwEditComp = () => {}
, 혹은 const index = () => {}
로 해주시면 좋을 것 같아요!
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.
공통된 부분은 컴포넌트로 따로 빼는 연습을 많이 하시면 좋을 것 같아요~!
그리고 스타일 컴포넌트도 같은 부분은 공통으로 사용할 수 있는 common 폴더를 사용하고, 페이지 내에서 사용되는 컴포넌트는 따로 파일로 분리해서 관리하면 더 좋을 것 같아요~!
이번 주 과제 고생하셨습니다! 합세 파이팅🥧
@@ -0,0 +1 @@ | |||
export const BASE_URL = 'http://34.64.233.12:8080'; |
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.
p1: 서버 주소는 .env 파일로 빼주세요!
<InputSort>ID</InputSort> | ||
<div style={{width: '100%'}}> | ||
<Input | ||
onChange={(e) => setId(e.currentTarget.value)} | ||
type="text" | ||
placeholder="아이디를 입력하세요" | ||
/> | ||
{!id && <HelpP>아이디를 입력하세요</HelpP>} |
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: 저도 위 생각에 동의합니다. 스타일 코드가 이렇게 나뉘어져있으면 유지보수가 힘들어 질 수 있어요!
아래 링크와 같이 본인 스스로의 규칙을 만들면 좋아요! 그리고 그 규칙들을 협업하는 팀원들과 공유한다면 더 좋을 것 같아요!
<InputSort>ID</InputSort> | ||
<div style={{width: '100%'}}> | ||
<Input | ||
onChange={(e) => setId(e.currentTarget.value)} |
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: 저는 e.target.value
로 사용했는데 차이점을 알고 계시나요?
한 번 참고하시길 바랍니다!
<Input ref={idRef} id="idInput" type="text" /> | ||
</InputContaier> | ||
<InputContaier> | ||
<InputSort>비밀번호</InputSort> | ||
<div style={{width: '100%'}}> | ||
<Input ref={pwRef} id="pwInput" type="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: 저도 여기 궁금해요!
authenticationId: idRef.current?.value, | ||
password: pwRef.current?.value, | ||
nickname: nicknameRef.current?.value, | ||
phone: phoneRef.current?.value, |
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: 우와 state를 안쓰고 이렇게 하셨네요!
import {BASE_URL} from '../assets/base-url'; | ||
import {Info, Input, MoveButton, OneLine} from '../style/styleComponents'; | ||
|
||
export default function (props: any) { |
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: 그리고 여기 컴포넌트 부분은 pages 폴더가 아니라 따로 분리해주면 좋을 것 같아요!
그리고 네이밍도 const PwEditComp = () => {}
, 혹은 const index = () => {}
로 해주시면 좋을 것 같아요!
const newPwRef = useRef<HTMLInputElement>(null); | ||
const newAgainPwRef = useRef<HTMLInputElement>(null); | ||
|
||
function handleEditPw() { |
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: 여기도 화살표 함수로 바꾸면 좋을 것 같아요!
setPhone({}); | ||
}, [phoneRef.current?.value]);*/ | ||
|
||
function checkEachInput(props: React.RefObject<HTMLInputElement>) { |
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: 아래의 handleSignUp 함수는 화살표 함수로 작성했는데, 여기는 왜 그냥 함수로 작성하셨나요!? 혹시 본인만의 컨벤션이 있나요?
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>보운이의 로그인</title> | ||
</head> | ||
<body style="margin: 0px; background-color: rgb(184, 202, 186)"> |
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: 여기 글로벌 스타일로 빼면 좋을 것 같아요!
} | ||
|
||
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.
여기도 빈 태그 빼면 좋을 것 같아요!
✨ 구현 기능 명세
🧩 기본 과제
로그인 페이지
회원가입 페이지
마이페이지
🔥 심화 과제
메인페이지
로그인 페이지
회원가입 페이지
input이 비어있는 상태로 api연결 시도했을시
해당 input 테두리 색상 변경
input에 focus 맞추기
api요청 금지
전화번호 양식 정규표현식으로 자동입력되도록 설정 (숫자만 입력해도 "-"가 붙도록)
비밀번호 검증 유틸 함수 구현 (검증 통과되지 않을시 api요청 금지)
공유과제
링크 첨부(팀 블로그 링크) :
https://forweber.palms.blog/now-sopt-settings-bowoon
📌 내가 새로 알게 된 부분
const idRef = useRef<HTMLInputElement>(null); const pwRef = useRef<HTMLInputElement>(null); const nicknameRef = useRef<HTMLInputElement>(null); const phoneRef = useRef<HTMLInputElement>(null);
<InputSort>ID</InputSort> <div style={{width: '100%'}}> <Input onChange={(e) => setId(e.currentTarget.value)} type="text" placeholder="아이디를 입력하세요" />
💎 구현과정에서의 고민과정(어려웠던 부분) 공유!
<Input ref={idRef} id="idInput" type="text" />
🥺 소요 시간
7h
🌈 구현 결과물
https://oceanic-ant-b58.notion.site/e6bc6909520f45518681bbf706b03ff0?pvs=4