
회원가입 페이지를 구성할때 어떤 것들이 필요 할까요?
먼저 form 과 input이 필요하겠죠.
input에는 id, nickname, password, passwordCheck를 만들 것 입니다.
password와 passwordCheck가 다를 경우 오류 메세지를 보이게 할 것입니다.
또한 간단하게 약관동의를 만들 건데요.
유저가 약관동의를 안할경우 또한 오류메세지를 보이게 할 것입니다.
import AppLayout from "../components/AppLayout";
import Head from "next/head";
import { Form, Input, Checkbox, Button } from "antd";
import { useCallback, useState } from "react";
import useInput from "../hooks/useInput";
import styled from "styled-components";
const ErrorMessage = styled.div`
color: red;
`;
const Signup = () => {
//state는 나중에 만들겁니다
return (
<>
<Head>
<title>회원가입 | NodeBird</title>
</Head>
<AppLayout>
<Form onFinish={onSubmit}>
{/* id input */}
<div>
<label htmlFor="user-id">아이디</label>
<br />
<Input name="user-id" value={id} required onChange={onChangeId} />
</div>
{/* nickname input */}
<div>
<label htmlFor="user-id">닉네임</label>
<br />
<Input
name="user-id"
value={nickname}
required
onChange={onChangeNickname}
/>
</div>
{/* password input */}
<div>
<label htmlFor="user-id">비밀번호</label>
<br />
<Input
name="user-id"
type="password"
value={password}
required
onChange={onChangePassword}
/>
</div>
{/* passwordCheck input*/}
<div>
<label htmlFor="user-id">비밀번호 체크</label>
<br />
<Input
name="user-id"
type="password"
value={passwordCheck}
required
onChange={onChangePasswordCheck}
/>
{passwordError && (
<ErrorMessage>비밀번호가 일치하지 않습니다.</ErrorMessage>
)}
</div>
{/* 약관동의 */}
<div>
<Checkbox name="user-term" checked={term} onChange={onChangeTerm}>
말을 잘 들을 것을 동의합니다.
</Checkbox>
{termError && (
<ErrorMessage>약관에 동의하셔야 합니다.</ErrorMessage>
)}
</div>
<div style={{ marginTop: 10 }}>
<Button type="primary" htmlType="submit">
가입하기
</Button>
</div>
</Form>
</AppLayout>
</>
);
};
export default Signup;
이제 input에 대한 state를 만들 차례인데요. 근데 한가지 문제가 있습니다. input하나하나 마다 value와 onChange이벤트를 달고 그 이벤트에대한 state, eventHandler 코드를 작성한다면 코드양이 너무 많아 질 것입니다. 그래서 공통된 부분은 Custom Hook을 만들어 코드양을 줄이고자 합니다.
hooks폴더를 만들고 useInput.js파일을 만들어 봅시다.
useInput.js
import { useState, useCallback } from "react";
export default initialValue => {
const [value, setValue] = useState(initialValue);
const handler = useCallback(e => {
setValue(e.target.value);
}, []);
return [value, handler];
};
이제 위의 useInput을 사용하여 signup.js를 완성해 볼까요?
signup.js
import AppLayout from "../components/AppLayout";
import Head from "next/head";
import { Form, Input, Checkbox, Button } from "antd";
import { useCallback, useState } from "react";
import useInput from "../hooks/useInput";
import styled from "styled-components";
const ErrorMessage = styled.div`
color: red;
`;
const Signup = () => {
//id input
const [id, onChangeId] = useInput("");
//nickname input
const [nickname, onChangeNickname] = useInput("");
//password input
const [password, onChangePassword] = useInput("");
const [passwordCheck, setPasswordCheck] = useState("");
// passwordError 초기값은 false
const [passwordError, setPasswordError] = useState(false);
// passowrd와 passwordCheck의 value가 다르면 passwordError를 true로
const onChangePasswordCheck = useCallback(
e => {
setPasswordCheck(e.target.value);
setPasswordError(e.target.value !== password);
},
[password]
);
//term (약관동의)
const [term, setTerm] = useState("");
// termError 초기값은 false
const [termError, setTermError] = useState(false);
// 약관동의를 한 경우 termError를 false로
const onChangeTerm = useCallback(e => {
setTerm(e.target.checked);
setTermError(false);
}, []);
// submit버튼을 눌렀을경우 password와 term을 한번더 확인
const onSubmit = useCallback(() => {
// passowrd와 passwordCheck가 다르면 passwordError를 true로
if (password !== passwordCheck) {
return setPasswordError(true);
}
// 약관동의를 안할경우 setTermError를 true로
if (!term) {
return setTermError(true);
}
console.log(id, nickname, password);
}, [password, passwordCheck, term]);
return (
<>
<Head>
<title>회원가입 | NodeBird</title>
</Head>
<AppLayout>
<Form onFinish={onSubmit}>
<div>
<label htmlFor="user-id">아이디</label>
<br />
<Input name="user-id" value={id} required onChange={onChangeId} />
</div>
<div>
<label htmlFor="user-id">닉네임</label>
<br />
<Input
name="user-id"
value={nickname}
required
onChange={onChangeNickname}
/>
</div>
<div>
<label htmlFor="user-id">비밀번호</label>
<br />
<Input
name="user-id"
type="password"
value={password}
required
onChange={onChangePassword}
/>
</div>
<div>
<label htmlFor="user-id">비밀번호 체크</label>
<br />
<Input
name="user-id"
type="password"
value={passwordCheck}
required
onChange={onChangePasswordCheck}
/>
{passwordError && (
<ErrorMessage>비밀번호가 일치하지 않습니다.</ErrorMessage>
)}
</div>
<div>
<Checkbox name="user-term" checked={term} onChange={onChangeTerm}>
말을 잘 들을 것을 동의합니다.
</Checkbox>
{termError && (
<ErrorMessage>약관에 동의하셔야 합니다.</ErrorMessage>
)}
</div>
<div style={{ marginTop: 10 }}>
<Button type="primary" htmlType="submit">
가입하기
</Button>
</div>
</Form>
</AppLayout>
</>
);
};
export default Signup;