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)
댓글 남기기