1. State 방법 로그인 처리

Input.jsx
//재사용이 가능한 컴포넌트 구축 및 활용
export default function Input({ label, id, error, ...props }) {
return (
<div className="control no-margin">
<label htmlFor={id}>{label}</label>
<input id={id} {...props} />
<div className="control-error">{error && <span>{error}</span>}</div>
</div>
);
}
Login.jsx
import { useEffect, useState } from "react";
import { isValidEmail, isNotEmpty, isValidPassword } from "../util/validation";
import Input from "./input";
export default function Login() {
// const [emailIsIvalid, setEmailIsIvalid]=useState(false);
// const [passwordIsIvalid, setPasswordIsIvalid]=useState(false);
//inut 데이터 저장하는 state
const [enteredValues, setEnterValues] = useState({
email: "",
password: "",
});
//유효성 검사를 위한 state
const [didEdit, setDidEdit] = useState({
email: false,
password: false,
});
// useEffect(() => {
// //이메일 유효성 체크
// setEmailIsIvalid(didEdit.email && (!isValidEmail(enteredValues.email) || !isNotEmpty(enteredValues.email) ));
// console.log("enteredValues.password " ,enteredValues.password);
// //비밀번호 유효성 체크
// setPasswordIsIvalid(didEdit.password && (!isValidPassword(enteredValues.password) || !isNotEmpty(enteredValues.password)) );
// },[didEdit]);
//true 면 이메일이유효하지 않음, input 에서 blue 가되면 true && 값이 없으면 true && 이메일이 유효하지 않으면 true
const emailIsIvalid = didEdit.email && (!isValidEmail(enteredValues.email) || !isNotEmpty(enteredValues.email) );
const passwordIsIvalid= didEdit.password && (!isValidPassword(enteredValues.password) || !isNotEmpty(enteredValues.password) );
//폼전송
function handleSubmit(event) {
event.preventDefault();
//console.log("email :", enteredValues.email, !isNotEmpty(enteredValues.email), ",password : ", !isNotEmpty(enteredValues.password));
// if(!isNotEmpty(enteredValues.email){
// }
// !isNotEmpty(enteredValues.password)) {
// console.log("Email is valid :");
// return;
// }
//폼전송전 객체를 돌면서 체크
let invalidCheck = false;
for (const key in enteredValues) {
setDidEdit((prevValues) => ({ ...prevValues, [key]: true }));
if (emailIsIvalid || passwordIsIvalid) {
invalidCheck = true;
}
}
if (invalidCheck) {
console.log("error!")
return;
}
console.log("pass!")
}
//폼 입력
function handleInputChange(identifier, value) {
setEnterValues((prevValues) => ({
...prevValues,
[identifier]: value,
}));
//초기화
setDidEdit((prevEdit) => ({
...prevEdit,
[identifier]: false,
}));
}
//INPUT 에 포커스가 흐려지면 didEdit 에 데이터를 넣게 되고 이것은 곧 => 유효성 검사로 연결 된다.
function handleInputBlue(identifier) {
setDidEdit((prevEdit) => ({
...prevEdit,
[identifier]: true,
}));
}
return (
<form onSubmit={handleSubmit}>
<h2>로그인</h2>
<div className="control-row">
<Input
label="이메일"
id="email"
type="email"
name="email"
onBlur={() => handleInputBlue("email")}
onChange={(event) => handleInputChange("email", event.target.value)}
value={enteredValues.email}
placeholder="이메일을 입력해 주세요."
error={emailIsIvalid && <p>이메일값이 유효하지 않습니다.</p>}
/>
<Input
label="비밀번호"
id="password"
type="password"
name="password"
onBlur={() => handleInputBlue("password")}
onChange={(event) => handleInputChange("password", event.target.value)}
value={enteredValues.password}
required
placeholder="대문자,특수문자,숫자를 포함하는 6~15자리"
error={passwordIsIvalid && <p>비밀번호값이 유효하지 않습니다.</p>}
/>
</div>
<p className="form-actions">
<button type="reset" className="button button-flat">초기화</button>
<button type="button" className="button" onClick={handleSubmit}>
로그인
</button>
</p>
</form>
);
}
2. userRef 방법 로그인 처리

import { useRef, useState } from "react";
//이메일 유효성 검사 함수
function emailValidChk(email) {
const pattern = /^[A-Za-z0-9_\.\-]+@[A-Za-z0-9\-]+\.[A-za-z0-9\-]+/;
if(pattern.test(email) === false) { return false; }
else { return true; }
}
export default function Login() {
const [emailIsInvalid, setEmailIsInvalid] =useState(false);
const email=useRef();
const password=useRef();
// 폼 제출 이벤트를 처리하는 함수를 정의합니다.
function handleSubmit(event){
event.preventDefault();
const enteredEmail =email.current.value;
const enteredPassword =password.current.value;
if(!emailValidChk(enteredEmail)){
setEmailIsInvalid(true);
return;
}
setEmailIsInvalid(false);
console.log("Sending HTTP request....");
}
return (
<form onSubmit={handleSubmit}>
<h2>로그인</h2>
<div className="control-row">
<div className="control no-margin">
<label htmlFor="email">이메일</label>
<input id="email" type="email" name="email" ref={email} />
<div className="control-error">
{emailIsInvalid && <p>이메일값이 유효하지 않습니다.</p>}
</div>
</div>
<div className="control no-margin">
<label htmlFor="password">비밀번호</label>
<input id="password" type="password" name="password" ref={password} />
</div>
</div>
<p className="form-actions">
<button className="button button-flat">초기화</button>
<button type="button" className="button" onClick={handleSubmit}>로그인</button>
</p>
</form>
);
}
3. 멀티 폼 회원 가입 처리
다음과 같이 Object.fromEntries() 로 formDta.entries() 처리를 하면 쉽게 폼데이터를 가져 올수 있다.
그리고 유효 성 검사 체크는 백엔드에서 작업처리 하는 방법이다.
https://github.com/braverokmc79/macaronics-react-food
function handleSubmit(event){
event.preventDefault();
const fd=new FormData(event.target);
const customerData =Object.fromEntries(fd.entries());
console.log("formData ==>" ,customerData);
console.log("formData ==>" ,customerData['email']);
}
서버 nodejs 샘플
app.post("/orders", async (req, res) => {
const orderData = req.body.order;
if (
orderData === null ||
orderData.items === null ||
orderData.items.length === 0
) {
return res.status(400).json({ message: "데이터가 누락되었습니다.." });
}
if (
orderData.customer.email === null ||
!orderData.customer.email.includes("@") ||
orderData.customer.name === null ||
orderData.customer.name.trim() === "" ||
orderData.customer.address === null ||
orderData.customer.address.trim() === "" ||
orderData.customer["postal-code"] === null ||
orderData.customer["postal-code"].trim() === "" ||
orderData.customer.phone === null ||
orderData.customer.phone.trim() === ""
) {
return res.status(400).json({
message:
"데이터 누락: 이메일, 이름, 주소, 우편번호 또는 전화번호가 누락되었습니다..",
});
}
const newOrder = {
...orderData,
id: (Math.random() * 1000).toString(),
};
const orders = await fs.readFile("backend/data/orders.json", "utf8");
const allOrders = JSON.parse(orders);
allOrders.push(newOrder);
await fs.writeFile("backend/data/orders.json", JSON.stringify(allOrders));
res.status(201).json({ message: "주문이 생성되었습니다!" });
});


import { useState } from "react";
export default function Signup() {
const [passwordsAreNotEqual, setPasswordsAreNotEqual]=useState(false);
function handleSubmit(event){
event.preventDefault();
const fd= new FormData(event.target);
const acquisitionChannle=fd.getAll('acquisition');
const termsChannel=fd.getAll('terms');
const data=Object.fromEntries(fd.entries());
data.acquisition=acquisitionChannle;
data.terms=termsChannel;
if(data.password !==data['confirm-password']){
setPasswordsAreNotEqual(true);
return;
}
event.target.reset();
}
return (
<form onSubmit={handleSubmit}>
<h2>환영합니다!</h2>
<p>회원 가입 ????</p>
<div className="control">
<label htmlFor="email">이메일</label>
<input id="email" type="email" name="email" required />
</div>
<div className="control-row">
<div className="control">
<label htmlFor="password">비밀번호</label>
<input id="password" type="password" name="password" required minLength={6} />
</div>
<div className="control">
<label htmlFor="confirm-password">비밀번호 확인</label>
<input
id="confirm-password"
type="password"
name="confirm-password"
required
minLength={6}
/>
<div className="control-error">{passwordsAreNotEqual && <p>비밀번호가 일치하지 않습니다.</p>}</div>
</div>
</div>
<hr />
<div className="control-row">
<div className="control">
<label htmlFor="last-name">성</label>
<input type="text" id="last-name" name="last-name" required />
</div>
<div className="control">
<label htmlFor="first-name">이름</label>
<input type="text" id="first-name" name="first-name" required />
</div>
</div>
<div className="control">
<label htmlFor="phone">직업이 어떻게 되십니까?</label>
<select id="role" name="role" required>
<option value="student">학생</option>
<option value="teacher">선생님</option>
<option value="employee">지작인</option>
<option value="founder">자영업</option>
<option value="other">기타</option>
</select>
</div>
<fieldset>
<legend>이 사이트를 어떻게 방문하게 되었습니까?</legend>
<div className="control">
<input
type="checkbox"
id="google"
name="acquisition"
value="google"
/>
<label htmlFor="google">구글</label>
</div>
<div className="control">
<input
type="checkbox"
id="friend"
name="acquisition"
value="friend"
/>
<label htmlFor="friend">친구 소개</label>
</div>
<div className="control">
<input type="checkbox" id="other" name="acquisition" value="other" />
<label htmlFor="other">기타</label>
</div>
</fieldset>
<div className="control">
<label htmlFor="terms-and-conditions">
<input type="checkbox" id="terms-and-conditions" name="terms" required />
이용 약관에 동의합니다.
</label>
</div>
<p className="form-actions">
<button type="reset" className="button button-flat">
초기화
</button>
<button type="submit" className="button">
회원가입
</button>
</p>
</form>
);
}
4. 로그인 hook 처리
useInput.jsx
import { useState } from "react";
export default function useInput(defaultValue, validationFn) {
// enteredValue와 setEnterValue는 입력된 값을 관리하는 상태입니다.
const [enteredValue, setEnterValue] = useState(defaultValue);
// didEdit와 setDidEdit는 입력 필드가 수정되었는지 여부를 관리하는 상태입니다.
const [didEdit, setDidEdit] = useState(false);
// valueIsValid는 입력된 값이 유효한지 여부를 확인합니다.
const valueIsValid = validationFn(enteredValue);
// handleInputChange는 입력 변경 이벤트를 처리하는 함수입니다.
function handleInputChange(event) {
// 입력된 값을 상태로 설정합니다.
setEnterValue(event.target.value);
// 입력이 변경되면 didEdit 상태를 false로 초기화 설정합니다.
setDidEdit(false);
}
// handleInputBlur는 입력 필드에서 포커스가 벗어났을 때 호출되는 함수입니다.
function handleInputBlur(identifier) {
// 입력 필드에서 포커스가 벗어났을 때 didEdit 상태를 true로 설정합니다.
setDidEdit(true);
}
// 이 훅은 다음의 값을 반환합니다:
return {
value: enteredValue, // 입력된 값
handleInputChange, // 입력 변경 이벤트 핸들러
handleInputBlur, // 입력 필드에서 포커스가 벗어난 이벤트 핸들러
hasError: didEdit && !valueIsValid, // 입력 값에 오류가 있는지 여부
setDidEdit // didEdit 상태를 설정하는 함수
}
}
Login.jsx
import { isValidEmail, isNotEmpty, isValidPassword } from "../util/validation";
import Input from "./input";
import useInput from "../hooks/useInput";
export default function Login() {
const {value:emailValue, handleInputChange:handleEmailChange,
handleInputBlue:handleEmailBlur, hasError:emaildHasError, setDidEdit:setEmailEdit} =useInput('', (value)=>isValidEmail(value) && isNotEmpty(value));
const {value:passwordValue, handleInputChange:handlePasswordChange,
handleInputBlue:handlePasswordBlur, hasError:passwordHasError, setDidEdit:setPasswordEdit} =useInput('', (value)=>isValidPassword(value) && isNotEmpty(value));
//폼전송
function handleSubmit(event) {
event.preventDefault();
setEmailEdit(true);
setPasswordEdit(true);
if(emaildHasError||passwordHasError){
console.log("error!")
return;
}
console.log("pass!")
}
return (
<form onSubmit={handleSubmit}>
<h2>로그인</h2>
<div className="control-row">
<Input
label="이메일"
id="email"
type="email"
name="email"
onChange={handleEmailChange}
onBlur={handleEmailBlur}
value={emailValue}
placeholder="이메일을 입력해 주세요."
error={ emaildHasError && <p>이메일값이 유효하지 않습니다.</p>}
/>
<Input
label="비밀번호"
id="password"
type="password"
name="password"
onChange={handlePasswordChange}
onBlur={handlePasswordBlur}
value={passwordValue}
required
placeholder="대문자,특수문자,숫자를 포함하는 6~15자리"
error={ passwordHasError && <p>비밀번호값이 유효하지 않습니다.</p>}
/>
</div>
<p className="form-actions">
<button type="reset" className="button button-flat">초기화</button>
<button type="button" className="button" onClick={handleSubmit}>
로그인
</button>
</p>
</form>
);
}
5. SimpleInput

import React, { useState } from 'react'
const SimpleInput = (props) => {
const [enteredName, setEnteredName] = useState('');
const [enteredNameTouched, setEnteredNameTouched] = useState(false);
const [enteredEmail, setEnteredEmail] = useState('');
const [enteredEmailTouched, setEnteredEmailTouched] = useState(false);
const enteredNameIsValid = enteredName.trim() !== '';
const nameInputIsInvalid = !enteredNameIsValid && enteredNameTouched;
const enteredEmailIsValid = enteredEmail.includes('@');
const emailInputIsInvalid = !enteredEmailIsValid && enteredEmailTouched;
let formIsValid = false;
if (enteredNameIsValid && enteredEmailIsValid) {
formIsValid = true;
}
const nameInputChangeHandler = (event) => {
setEnteredName(event.target.value);
}
const emailInputChangeHandler = (event) => {
setEnteredEmail(event.target.value);
}
const formSubmissionHandler = (event) => {
event.preventDefault();
setEnteredNameTouched(true);
setEnteredEmailTouched(true);
if (!enteredNameIsValid || !enteredEmailIsValid) {
return;
}
console.log(enteredName);
console.log(enteredEmail);
setEnteredName('');
setEnteredNameTouched(false);
setEnteredEmail('');
setEnteredEmailTouched(false);
}
const nameInputClasses = nameInputIsInvalid ? 'form-control invalid' : 'form-control';
const emailInputClasses = emailInputIsInvalid ? 'form-control invalid' : 'form-control';
const nameInputBlurHandler = () => {
setEnteredNameTouched(true);
}
const emailInputBlurHandler = () => {
setEnteredEmailTouched(true);
}
return (
<form onSubmit={formSubmissionHandler}>
<div className={nameInputClasses}>
<label htmlFor="name">이름</label>
<input
type="text"
id="name"
onChange={nameInputChangeHandler}
onBlur={nameInputBlurHandler}
value={enteredName}
/>
{nameInputIsInvalid && (<p className='error-text'>Name must not be empty</p>)}
</div>
<div className={emailInputClasses}>
<label htmlFor="email">이메일</label>
<input
type="email"
id="email"
onChange={emailInputChangeHandler}
onBlur={emailInputBlurHandler}
value={enteredEmail}
/>
{emailInputIsInvalid && (<p className='error-text'>Email must not be empty and should contain '@'</p>)}
</div>
<div className='form-actions'>
<button disabled={!formIsValid}>Submit</button>
</div>
</form>
);
}
export default SimpleInput;
11.리액트 - 회원가입 및 로그인 양식 및 사용자 입력작업
(17양식 및 사용자 입력작업)
https://macaroncis-react-form-sign-sample.netlify.app/

소스 :https://github.com/braverokmc79/macaroncis-react-form-sign-sample














댓글 ( 0)
댓글 남기기