티스토리 뷰
Today I Learned
오늘 로그인, 회원가입 기능 구현을 끝냈다!
프론트엔드, 백엔드 모두 꼼꼼하게 확인한 덕분에 API 통신도 에러 없이 한 번에 됐다.
개인과제에서 파이어베이스 Auth 서비스로 회원가입, 로그인을 만들어본 적은 있지만
프로젝트에서 회원가입, 로그인을 담당하게 된 건 처음이었는데 문제 없이 잘 작동해서 다행이라고 생각했다.
📍 회원가입, 로그인 유효성 검사
백엔드에서 이미 회원가입, 로그인에 대한 유효성 검사를 처리해주었지만
프론트엔드에서도 이중으로 유효성 검사를 설정해주면 더 좋다는 얘기를 들은 적이 있어서
프론트엔드에서 할 수 있는 만큼의 유효성 검사를 설정했다.
Unsplash 회원가입 페이지에서는 아래와 같이
회원가입 입력값의 조건이 맞지 않을 경우 label과 input의 border 컬러가 변한다.
나도 조건에 따라 className을 다르게 설정하도록 해서
조건에 맞지 않을 경우 원래의 사이트와 동일하게 label과 input의 border 컬러가 변하도록 만들었다.
추가로 각 입력 필드의 작성 조건을 조금 더 상세하게 적고,
네 개의 필드 중 하나라도 조건에 부합하지 않거나 비어있는 경우 Join 버튼을 비활성화하였다.
이렇게 하면 백엔드에서 보내주는 회원가입 에러 메시지의 수가 훨씬 적어진다.
// ...
// 유저가 input에 입력한 value의 길이가 1 이상이면서
// Validation(Regexp) 에 부합하지 않는 경우 className='has-error'
<Grid height="auto">
<FormGroup className={`${fullname.length > 0 && !isFullname ? 'has-error' : 'success'}`}>
<label className="form-label">Full name</label>
<input className="form-input" name="fullname" onChange={onChangeFullname}></input>
</FormGroup>
<FormGroup className={`${email.length > 0 && !isEmail ? 'has-error' : 'success'}`}>
<label className="form-label">Email address</label>
<input className="form-input" name="email" onChange={onChangeEmail}></input>
</FormGroup>
<FormGroup className={`${nickname.length > 0 && !isNickname ? 'has-error' : 'success'}`}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'left' }}>
<label className="form-label">Username</label>
<span>
<Validation> (only letters, numbers, and underscores & min. 3 char, max. 16 char)</Validation>
</span>
</div>
<input className="form-input" name="nickname" onChange={onChangeNickname} maxLength="16"></input>
</FormGroup>
<FormGroup className={`${password.length > 0 && !isPassword ? 'has-error' : 'success'}`}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'left' }}>
<label className="form-label">Password</label>
<span>
<Validation> (only letters, numbers, and special char & min. 6 char, max. 20 char)</Validation>
</span>
</div>
<input className="form-input" type="password" name="password" onChange={onChangePassword} maxLength="20"></input>
</FormGroup>
</Grid>
// ...
// ...
// className이 has-error일 경우 적용되는 styled-components
.has-error {
.form-label {
color: #e25c3d;
}
.form-input {
border: 1px solid #e25c3d;
&:focus {
border: 1px solid #e25c3d;
}
}
}
// ...
📍 styled-components - Globalstyles
이번 프로젝트에서도 styled-components 부분의 코드가 길어지고 지저분해지는 걸 보면서
저번 주에 찬수님이 알려준 styled-components의 globalstyles가 생각나서 찾아본 후 이번 클론 코딩에 적용해보았다.
1) Shared 폴더에 GlobalStyles.js 파일 생성 후 createGlobalStyle import
2) 전역에 적용해야 하는 CSS 속성 설정 후 export
3) 실행 파일 (App.js)에 GlobalStyle import 후 최상위 컴포넌트 위치에 적용
// GlobalStyle.js
import { createGlobalStyle } from 'styled-components'
const GlobalStyle = createGlobalStyle`
*, *::before, *::after {
box-sizing : border-box;
}
body {
color: #111;
/* font-family: -apple-system,BlinkMacSystemFont,San Francisco,Helvetica Neue,Helvetica,Ubuntu,Roboto,Noto,Segoe UI,Arial,sans-serif; */
font-size: 15px;
font-weight: 400;
line-height: 1.6;
}
input {
outline: none;
}
input:focus {
outline: none;
border: none;
}
button {
cursor: pointer;
outline: none;
border: none;
background-color: #FFF;
}
a {
cursor: pointer;
}
`
export default GlobalStyle
// App.js
import React from 'react'
import { Route } from 'react-router-dom'
import Login from '../pages/Login'
import Join from '../pages/Join'
import Detail from '../pages/Detail'
import Edit from '../pages/Edit'
import Main from '../pages/Main'
import Sub from '../pages/Sub'
import Upload from '../pages/Upload'
import Mypage from '../pages/Mypage'
import { ConnectedRouter } from 'connected-react-router'
import { history } from '../redux/configureStore'
import GlobalStyle from './GlobalStyle'
function App() {
return (
<>
<ConnectedRouter history={history}>
<GlobalStyle />
<Route path="/" exact component={Main} />
<Route path="/sub/:tag" exact component={Sub} />
<Route path="/login" exact component={Login} />
<Route path="/join" exact component={Join} />
<Route path="/detail" exact component={Detail} />
<Route path="/edit" exact component={Edit} />
<Route path="/upload" exact component={Upload} />
<Route path="/mypage/:nickname" exact component={Mypage} />
</ConnectedRouter>
</>
)
}
export default App
styled-components는 한 컴포넌트 안에서만 사용할 수 있어서
box-sizing이나, 공통으로 사용하는 font 속성들, button이나 input 태그 사용 시 제거해줘야 하는 기본 속성들을
모든 컴포넌트들 마다 하나하나 적용해줘야 하는 불편함이 있었다.
Globalstyle을 사용하면 코드가 훨씬 줄어들고 깔끔해지면서,
UI 측면에서도 페이지나 컴포넌트마다 통일성을 가질 수 있어서 좋은 것 같다.
'what i learned > TIL' 카테고리의 다른 글
[TIL] 2021/12/21 Tue - (2) | 2021.12.21 |
---|---|
[TIL] 2021/12/16 Thu - My page (0) | 2021.12.16 |
[TIL] 2021/12/13 Mon - (2) | 2021.12.13 |
[TIL] 2021/12/10 Fri - (0) | 2021.12.10 |
[TIL] 2021/12/06 Mon - (0) | 2021.12.06 |