React

 

 

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

노동 뒤의 휴식이야말로 가장 편안하고 순수한 기쁨이다. -칸트-

댓글 ( 0)

댓글 남기기

작성