일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- @JUnit
- STS
- @Spring-Test
- java
- AOP
- spring
- spring framework
- JDBC TEMPLATE
- pointcut
- 마이바티스
- JdbcTemplate
- Linux
- 컨테이너
- java spring
- Di
- Spring Boot
- Framework
- @test
- myBatis
- @AspectJ
- Spring JDBC
- POJO
- 프로퍼티
- 리눅스
- SpringJDBC
- spring aop
- unix
- XML
- Ubunt
- Dependency Injection
Archives
- Today
- Total
개키우는개발자 : )
React SNS 2-4. 커스텀 훅 재사용하기 본문
반응형
로그인 폼 만들기
dummy 데이터의 isLoggedIn : true 이면 로그인 상태 false 이면 로그아웃 상태를 삼항 연산자로 비교를 하였습니다.
import React from 'react';
import Link from 'next/link';
import {Menu, Input , Button, Row , Col , Card , Avatar , Form} from 'antd';
import PropTypes from 'prop-types';
const dummy = {
nickname : 'Dogveloper',
Post : [],
Followings : [],
Followers : [],
isLoggedIn : true,
};
const AppLayout = ({children}) =>{
return (
<div>
<Menu mode="horizontal">
<Menu.Item key="home"><Link href="/"><a>노드버드</a></Link></Menu.Item>
<Menu.Item key="profile"><Link href="/profile"><a>프로필</a></Link></Menu.Item>
<Menu.Item key="mail">
<Input.Search enterButton style={{verticalAlign:'middle'}} />
</Menu.Item>
</Menu>
<Row>
<Col xs={24} md={6} >
{dummy.isLoggedIn
?<Card
actions={[
<div key="twit">짹짹<br/>{dummy.Post.length}</div>,
<div key="following">팔로잉<br/>{dummy.Followings.length}</div>,
<div key="follower">팔로워<br/>{dummy.Followers.length}</div>,
]}
>
<Card.Meta
avatar={<Avatar>{dummy.nickname[0]}</Avatar>}
title={dummy.nickname}
/>
</Card>
:
<Form>
<div>
<label htmlFor="user-id">아이디</label>
<br />
<Input name="user-id"/>
</div>
<div>
<label htmlFor="user-id">비밀번호</label>
<br />
<Input name="user-id" type="password" />
</div>
<div>
<Button type="primary" htmlType="submit" loading={false} >로그인</Button>
<Link href="/signup"><a><Button>회원가입</Button></a></Link>
</div>
</Form>
}
</Col>
<Col xs={24} md={12} >{children}</Col>
<Col xs={24} md={6} >세번째</Col>
</Row>
</div>
);
};
AppLayout.propTypes = {
children : PropTypes.node,
};
export default AppLayout;
isLoggedIn : true
isLoggedIn : false
하지만 로그인 폼의 문제점중 하나가 로그인 영역에서 setStatus를 할 때마다 모든 영역이 리 랜더링 되면서 쓸모없는 리소스가 소모됩니다. 그렇기 때문에 loginForm을 따로 컴포넌트 합니다.
영역을 나눠야 할때 헷갈리는 부분이 많으므로 일단 한 곳에 작성 후 그 이후에 나누어 주면 편하게 나눌 수 있습니다.
component 폴더 안에 LoginForm.js 를만듭니다.
LoginForm.js
import React, { useCallback } from 'react';
import { Input , Form , Button } from 'antd';
import Link from 'next/link';
import { useInput } from '../pages/signup';
const LoginForm = () => {
const [id , onChangeId] = useInput('');
const [password , onChangePassword] = useInput('');
const onSubmitForm = useCallback((e) => {
e.preventDefault();
console.log({
id,
password
})
},[id,password]);
return (
<Form onSubmit={onSubmitForm}>
<div>
<label htmlFor="user-id">아이디</label>
<br />
<Input name="user-id" value={id} onChange={onChangeId} />
</div>
<div>
<label htmlFor="user-id">비밀번호</label>
<br />
<Input name="user-id" type="password" value={password} onChange={onChangePassword} />
</div>
<div>
<Button type="primary" htmlType="submit" loading={false} >로그인</Button>
<Link href="/signup"><a><Button>회원가입</Button></a></Link>
</div>
</Form>
);
}
export default LoginForm;
이전 포스팅에서 signup.js 에 custom hook을 만들어놓은 게 있다. 그 커스텀 훅을 import 받아와서 로그인 폼에서 사용할 수가 있다.
signup.js
import React, {useState, useCallback, memo} from 'react';
import { Form , Input , Checkbox , Button} from 'antd';
//퓨어 컴포넌트가 적용안된 컴포넌트를 강제로 적용시키기 위해 memo를 적용한다.
const TextInput = memo(({value, onChange , name , type}) => {
return (
<Input type={type} name={name} value={value} required onChange={onChange} />
);
});
//반복되는 코드들을 Coustom Hook을 활용하여 줄여줄 수 있다.
export const useInput = (initValue = null) =>{
const [value,setter] = useState(initValue);
const handler = useCallback((e) => {
setter(e.target.value);
},[]);
return [value,handler];
};
const Signup = () =>{
const [passwordCheck,setPasswordCheck] = useState('');
const [term,setTerm] = useState(false);
const [passwordError,setPasswordError] = useState(false);
const [termError,setTermError] = useState(false);
const onSubmit = useCallback((e) => {
e.preventDefault();
/**검증 로직 만들기
* 1. 비밀번호와 비밀번호 체크가 다를 경우를 검증한다
* 2. 약관 동의를 확인한다.
*/
if(password !== passwordCheck){
return setPasswordError(true);
}
if(!term){
return setTermError(true);
}
//useCallback 하면 state 들을 dependence 배열에 넣어줍니다.
//그래야 dependence 가 바뀔때 이벤트 함수가 생성이됩니다.
},[password,passwordCheck,term]);
const onChangePasswordChk = useCallback((e) => {
//비밀번호를 입력할때마다 password 를 검증하는 함수
setPasswordError(e.target.value !== password);
setPasswordCheck(e.target.value);
//password state를 사용하기때문에 password를 넣어준다
},[passwordCheck]);
const onChangeTerm = useCallback((e) => {
//체크박스 초기화
setTermError(false);
setTerm(e.target.checked);
//state를 사용하지 않기때문에 빈값
},[]);
const [id,onChangeId] = useInput('');
const [nick,onChangeNick] = useInput('');
const [password,onChangePassword] = useInput('');
return (
<>
<Form onSubmit={onSubmit} style={{padding:10}}>
<div>
<label htmlFor="user-id">아이디</label><br/>
<TextInput name="userId" type="text" value={id} onChange={onChangeId} />
</div>
<div>
<label htmlFor="user-nick">닉네임</label><br/>
<TextInput name="user-nick" type="text" value={nick} required onChange={onChangeNick} />
</div>
<div>
<label htmlFor="user-password">비밀번호</label><br/>
<TextInput name="user-password" type="password" value={password} required onChange={onChangePassword} />
</div>
<div>
<label htmlFor="user-password-check">비밀번호체크</label><br/>
<TextInput name="user-password-check" type="password" value={passwordCheck} required onChange={onChangePasswordChk} />
{passwordError && <div style={{color : 'red'}}>비밀번호가 일치하지 않습니다.</div>}
</div>
<div>
<Checkbox name="user-term" value={term} onChange={onChangeTerm}>동의 합니까?</Checkbox>
{termError && <div style={{color : 'red'}}>약관에 동의하셔야 합니다.</div>}
</div>
<div style={{marginTop:10}}>
<Button type="primary" htmlType="submit" >가입하기</Button>
</div>
</Form>
</>
);
};
export default Signup;
기존에 const Signup 안에 있던 코드를 밖으로 빼주고 const 앞에 export를 입력한다. 그럼 어디서든 사용할 수 있다.
실행
커스텀 훅이 잘 적용되는 걸 볼 수 있다.
출처 : https://www.youtube.com/channel/UCp-vBtwvBmDiGqjvLjChaJw
반응형
'React > React SNS Project' 카테고리의 다른 글
React SNS 2-6. 프로필 화면 만들기 (0) | 2019.05.17 |
---|---|
React SNS 2-5. 메인화면 만들기 (0) | 2019.05.17 |
React SNS 2-3. antd 그리드 시스템 (0) | 2019.05.17 |
React SNS 2-2. prop-types 와 next 기본 제공페이지 (0) | 2019.05.17 |
React SNS 2-1. _app.js로 레이아웃 분리하기 (0) | 2019.05.17 |
Comments