ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • react정리10
    카테고리 없음 2022. 8. 27. 22:07

    양식form 제출 처리 및 사용자 입력값 가져오기

    import { useRef, useState } from "react";
    
    const SimpleInput = (props) => {
    //useRef로 사용하는법
    const nameInputRef = useRef();
    const [enteredName, setEnteredName] = useState('');
    
    //사용자 입력 가져오기(useState나, useRef로 가져올 수 있다)
    const nameInputChangeHandler = event => {
      setEnteredName(event.target.value)
    }
    //폼이 제출될 때 작동하는 함수
    const formSubmissionHandler = event => {
      event.preventDefault();
      console.log(enteredName)
      //useRef사용
      const enteredValue = nameInputRef.current.value;
      console.log(enteredValue);
      //압력값 초기화 input value에서 state
      setEnteredName('')
    }
    
      return (
        <form onSubmit={formSubmissionHandler}>
          <div className='form-control'>
            <label htmlFor='name'>Your Name</label>
            <input ref={nameInputRef}type='text' id='name' onChange={nameInputChangeHandler} value={enteredName}/>
          </div>
          <div className="form-actions">
            <button>Submit</button>
          </div>
        </form>
      );
    };
    
    export default SimpleInput;

    유효성 검증 추가

    빈칸을 제출할 때 error 피드백 띄우기

    import { useRef, useState } from "react";
    
    const SimpleInput = (props) => {
    const nameInputRef = useRef();
    const [enteredName, setEnteredName] = useState('');
    //error출력 위한 상태 false로 하면 처음부터 error메세지가 뜨게 되므로 true로 설정해준다
    const [enteredNameIsValid, setEnteredNameIsValid] = useState(true);
    
    //사용자 입력 가져오기(useState나, useRef로 가져올 수 있다)
    //함수 만들고 input에서 onChange로 함수를 연결해준다
    const nameInputChangeHandler = event => {
      setEnteredName(event.target.value)
    }
    
    const formSubmissionHandler = event => {
      event.preventDefault();
      //유효성 검증
      //trim 공백제거 여기서 값이 없을 경우에 return하면 다음 줄이 실행되지 않는다
      if(enteredName.trim() == '') {
        //입력값이 유효하지 않다면 false로 설정
        setEnteredNameIsValid(false)
        return;
      }
      //앞의 조건문 다음으로 실행되는 것이 값이 유효하다는 의미이므로 true로 설정
      setEnteredNameIsValid(true);
      console.log(enteredName)
      //useRef사용
      const enteredValue = nameInputRef.current.value;
      console.log(enteredValue);
    
      //압력값 초기화 input value에서 state연결 후 사용가능
      setEnteredName('')
    }
    
    //class를 이용해 입력부분 보이는 방식 바꾸기(css)
    //form-control class를 입력값이 유효하지 않을 때 css에서 설정한 form-control invalid로 변경
    //true일 경우 form-control이 되고 false일 경우 orm-control invalid가 된다
    //className에서 함수명nameInputClasses으로 지정해준다
    const nameInputClasses = enteredNameIsValid ? 'form-control' : 'form-control invalid';
    
      return (
        <form onSubmit={formSubmissionHandler}>
          <div className={nameInputClasses}>
            <label htmlFor='name'>Your Name</label>
            <input ref={nameInputRef}type='text' id='name' onChange={nameInputChangeHandler} value={enteredName}/>
            {/**텍스트가 값이 유효하지 않을 때만 보이도록 설정 
             * enteredNameIsValid가 false일 때 p태그 표시
            */}
            {!enteredNameIsValid && <p className="error-text">Name must not be empty.</p>}
          </div>
          <div className="form-actions"> 
            <button>Submit</button>
          </div>
        </form>
      );
    };
    
    export default SimpleInput;

    유효성 검증 코드 수정

    import { useEffect, useRef, useState } from "react";
    
    const SimpleInput = (props) => {
    const nameInputRef = useRef();
    const [enteredName, setEnteredName] = useState('');
    //error출력 위한 상태 생성 초기값 fasle 즉, 처음에는 입력된 값이 유효하지 않음을 의미
    //false로 하면 처음부터 error메세지가 뜨게 되므로 true로 설정해준다-처음부터 true로 설정하는 것 맞지 않음
    //false가 권장됨 그래서 true로 설정한 유효성 코드는 임시방편, 다른 방법으로 실행
    const [enteredNameIsValid, setEnteredNameIsValid] = useState(false);
    //사용자가 입력을 건드렸을 경우,.
    const [enteredNameTouched, setEnteredNameTouched] = useState(false);
    
    //enteredNameIsValid가 변경될 때마다 실행,,,
    useEffect(()=> {
      if (enteredNameIsValid) {
        console.log('Name Input is valid');
      }
    }, [enteredNameIsValid])
    
    //사용자 입력 가져오기(useState나, useRef로 가져올 수 있다)
    //함수 만들고 input에서 onChange로 함수를 연결해준다
    const nameInputChangeHandler = event => {
      setEnteredName(event.target.value)
    }
    //폼이 제출될 때 작동하는 함수 form onSubit으로 연결
    const formSubmissionHandler = event => {
      //새로고침 막기
      event.preventDefault();
      //추가해준다
      setEnteredNameTouched(true);
    
    
    
      //유효성 검증
      //trim 공백제거 여기서 값이 없을 경우에 return하면 다음 줄이 실행되지 않는다
      if(enteredName.trim() == '') {
        //입력값이 유효하지 않다면 false로 설정
        setEnteredNameIsValid(false)
        return;
      }
      //앞의 조건문 뒤로 실행되는 것이 값 유효하다는 의미이므로 true로 설정
      setEnteredNameIsValid(true);
      console.log(enteredName)
      //useRef사용
      const enteredValue = nameInputRef.current.value;
      console.log(enteredValue);
      //useRef를 이용한 입력값 초기화->바람직하지 않음 useState사용 권장
      // nameInputRef.current.value = '';
      //압력값 초기화 input value에서 state연결 후 사용가능
      setEnteredName('')
    }
    
    //앞의 값은 false이고 touched는 true일 때 true가 되도록 한다
    //입력창이 건드려진 뒤면서 값이 유효하지 않을 때만 유효하지 않게 판단하기 위해서
    const nameInputIsInvalid = !enteredNameIsValid && enteredNameTouched
    
    //class를 이용해 입력부분 보이는 방식 바꾸기
    //form-control class를 입력값이 유효하지 않을 때 css에서 설정한 form-control invalid로 변경
    //true일 경우 form-control이 되고,,false일 경우 orm-control invalid가 된다
    //className에서 함수명nameInputClasses으로 지정해준다
    
    //추가로 위에 함수를 지정했으므로 반대로 바꿈
    const nameInputClasses = nameInputIsInvalid ? 'form-control invalid' : 'form-control'
    
    
      return (
        <form onSubmit={formSubmissionHandler}>
          <div className={nameInputClasses}>
            <label htmlFor='name'>Your Name</label>
            <input ref={nameInputRef}type='text' id='name' onChange={nameInputChangeHandler} value={enteredName}/>
            {/**텍스트가 값이 유효하지 않을 때만 보이도록 설정 
             * enteredNameIsValid가 false일 때 p태그 표시
            */}
            {nameInputIsInvalid && <p className="error-text">Name must not be empty.</p>}
          </div>
          <div className="form-actions"> 
            <button>Submit</button>
          </div>
        </form>
      );
    };
    
    export default SimpleInput;

    사용자가 입력할 때 errorr 표시

    input요소가 포커스를 잃었을 때 유효성 검증

    값이 유효하지 않은 상태에서 focus를 잃었을 때 사용자는 즉각적인 error메시지를 얻게 된다

    //input요소가 focus를 잃었을 때 유효성 검증하기 위한 함수 input의 onBlur 연결
    const nameInputBlurHandler =event => {
      //입력창에서 포커스를 잃었다는 것은 그 전에 사용자가 건드렸다는 것이고 입력할 기회가 있었다는 것
      setEnteredNameTouched(true)
    
      //유효성 검증 enteredName확인 후 값이 유효하지 않으면 setEnteredNameIsValid false로 바꿔준다
      if(enteredName.trim() == '') {
        setEnteredNameIsValid(false)
        return;
      }
    }

    사용자가 키를 입력할 때마다 값이 유효한지 즉각적인 피드백을 받을 수 있도록 표시

    키입력에 따라 고칠 수 있게 된다

    const nameInputChangeHandler = event => {
      setEnteredName(event.target.value)
    
      //키 입력마다 유효성 검증하기 입력마다 검증해기 때문에 event.target.value
      if(event.target.value.trim() !== '') {
        //입력값이 유효하지 않다면 false로 설정
        setEnteredNameIsValid(true)
      }
    }

    리펙토링

    import { useState } from "react";
    
    const SimpleInput = (props) => {
    const [enteredName, setEnteredName] = useState('');
    const [enteredNameTouched, setEnteredNameTouched] = useState(false);
    //
    const enteredNameIsValid = enteredName.trim() !== '';
    const nameInputIsInvalid = !enteredNameIsValid && enteredNameTouched
    
    const nameInputChangeHandler = event => {
      setEnteredName(event.target.value)
    }
    
    const nameInputBlurHandler =event => {
      setEnteredNameTouched(true)
    }
    
    const formSubmissionHandler = event => {
      event.preventDefault();
      setEnteredNameTouched(true);
      if(!enteredNameIsValid) {
        return;
      }
      console.log(enteredName)
      setEnteredName('')
      setEnteredNameTouched(false);
    }
    
    const nameInputClasses = nameInputIsInvalid ? 'form-control invalid' : 'form-control'
    
      return (
        <form onSubmit={formSubmissionHandler}>
          <div className={nameInputClasses}>
            <label htmlFor='name'>Your 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="form-actions"> 
            <button>Submit</button>
          </div>
        </form>
      );
    };
    
    export default SimpleInput;

    여러 입력을 받을 경우 전체 form이 유효한지 확인 전체 양식이 유효하기 위해서는 모든 입력이 유효해야 한다

    //deps에 폼의 입력의 모든 유효성 추가 enteredNameIsCalid 이 값이 바뀔 때마다 
    //useEffect가 다시 실행된다 컴포넌트가 처음 실행될 때도 실행된다
    //useEffect에서는 모든 deps를 합친 뒤에 이 값이 모두 유효한지 확인하고 그렇다면 전체 폼이 유효하다고 설정한다
    //useEffect를 사용하지 않아도 된다 이 대신 formIsValid와 useEffect를 없애고
    //enteredNameIsValid와 다른 유효성의 값이 있다면 &&으로 확인
    // useEffect(()=> {
    //   if (enteredNameIsValid ) {
    //     setFormIsValid(true);
    //   } else {
    //     setFormIsValid(false);
    //   }
    // },[enteredNameIsValid]);
    
    //useEffect사용하지 않는 방법
    let formIsValid = false;
    if (enteredNameIsValid ) {
      formIsValid = true;
    }

    사용자 이메일 받아오고 올바른 이메일 주소인지 유효성 검증

    import { useEffect, useState } from "react";
    
    const SimpleInput = (props) => {
    const [enteredName, setEnteredName] = useState('');
    const [enteredNameTouched, setEnteredNameTouched] = useState(false);
    //이메일 input관련 상태
    const [enteredEmail, setEnteredEmail] =useState('');
    const [enteredEmailTouched, setEnteredEmailTouched] = useState(false);
    
    const nameInputIsInvalid = !enteredNameIsValid && enteredNameTouched
    
    //이메일input enteredEmail이 @을 포함하는지 확인 이메일 관련 유효성 검사(간단한) 
    const enteredEmailIsValid = enteredEmail.includes('@');
    //위에서 만든 값이 false일 경우와 enteredEmailTouched가 true가 될 때
    //이 상수를 이용해 classes로 유효하지 않을 경우의 style변화를 준다 
    //error메시지 출력활용에도 사용
    const enteredEmailIsInValid = !enteredEmailIsValid && enteredEmailTouched
    
    //전체 폼 유효성 검증
    let formIsValid = false;
    if (enteredNameIsValid && enteredEmailIsValid) {
      formIsValid = true;
    }
    
    const nameInputChangeHandler = event => {
      setEnteredName(event.target.value)
    }
    
    //email Input
    const emailInputChangeHandler = event => {
      setEnteredEmail(event.target.value)
    }
    
    const nameInputBlurHandler =event => {
      setEnteredNameTouched(true)
    }
    
    //email input요소가 focus를 잃었을 때 유효성 검증하기 위한 함수 input의 onBlur 연결
    const emailInputBlurHandler = event => {
      setEnteredEmailTouched(true)
    }
    
    const formSubmissionHandler = event => {
      event.preventDefault();
      setEnteredNameTouched(true);
      if(!enteredNameIsValid) {
        return;
      }
      console.log(enteredName)
      //폼 submit버튼 제출 후 초기화
      setEnteredName('')
      setEnteredNameTouched(false);
     
      setEnteredEmail('')
      setEnteredEmailTouched(false);
    }
    
    const nameInputClasses = nameInputIsInvalid ? 'form-control invalid' : 'form-control';
    
    //값이 유효하지 않을 경우의 email부분 style변경
    const emailInputClasses = enteredEmailIsInValid ? 'form-control invalid' : 'form-control';
    
      return (
        <form onSubmit={formSubmissionHandler}>
          <div className={nameInputClasses}>
            <label htmlFor='name'>Your 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>
          {/* 이메일input */}
          <div className={emailInputClasses}>
            <label htmlFor='name'>Your E-Mail</label>
            <input type='email' id='email' onChange={emailInputChangeHandler} onBlur={emailInputBlurHandler}value={enteredEmail}/>
            {/**텍스트가 값이 유효하지 않을 때만 보이도록 설정 */}
            {enteredEmailIsInValid && <p className="error-text">Please enter a valid email.</p>}
          </div>
          <div className="form-actions"> 
            <button disabled={!formIsValid}>Submit</button>
          </div>
        </form>
      );
    };
    
    export default SimpleInput;

    사용자지정 custom hook 추가

    hooks/use-input.js

    //중복된 코드를 막기 위해 customhook사용
    //입력값과 입력창이 건드려졌는지에 대한 상태를 다룬다(중복되는것들)
    import { useState } from "react";
    
    //인자를 함수로 받는다 validateValue 이 매개변수가 함수를 값으로 받게 된다
    const useInput = (validateValue) => {
      //제네릭한 이름으로 바꿔줌 enteredName,touched가져와서 valid부분도 이름 다 바꿔줌
      const [enteredValue, setEnteredValue] = useState("");
      //사용자가 입력을 건드렸을 경우
      const [isTouched, setIsTouched] = useState(false);
    
      //인자로 매개변수 이름 설정 후valueIsValid를 validateValue에 enteredValue를 입력해 실행한 값으로 만든다
      const valueIsValid = validateValue(enteredValue);
      //앞의 값은 false이고 touched는 true일 때 true가 되도록 한다
      //입력창이 건드려진 뒤면서 값이 유효하지 않을 때만 유효하지 않게 판단하기 위해서
      const hasError = !valueIsValid && isTouched;
    
      const valueChangeHandler = (event) => {
        setEnteredValue(event.target.value);
      };
      //input요소가 focus를 잃었을 때 유효성 검증하기 위한 함수 input의 onBlur 연결
      const inputBlurHandler = (event) => {
        //입력창에서 포커스를 잃었다는 것은 그 전에 사용자가 건드렸다는 것이고
        //즉 입력할 기회가 있었다는 것
        setIsTouched(true);
      };
    
      //초기화(RESET) 함수
      const reset = () => {
        setEnteredValue("");
        setIsTouched(false);
      };
    
      //값 반환 hasError의 결과도 반환 value반환
      //모던 자바스크립트 문법으로 hasError 값 한번만 써준다 
      //이렇게 훅에서 정의된 함수들은 훅을 사용하는 컴포넌트에서 호출될 수 있다
      return {
        value: enteredValue,
        isValid: valueIsValid,
        hasError,
        valueChangeHandler,
        inputBlurHandler,
        reset,
      };
    };
    
    export default useInput;

    커스텀 훅 적용

    import { useState } from "react";
    
    //custom hook 불러오기
    import useInput from "../hooks/use-input";
    
    const SimpleInput = (props) => {
      //useInput호출하여 반환된 결과로부터 값을 추출(객체를 반환하므로 객체 디스트럭처링으로 키를 이용해 값을 가져온다)
      //value의 키값을 value:enteredName에 할당할 수 있다 이름 사용자설정
      //customhook에서 값을 입력해줘야 한다
      //함수를 다른 함수의 입력값으로 넣는 자바스크립트 문법
      const {
        value: enteredName,
        isValid: enteredNameIsValid,
        hasError: nameInputHasError,
        valueChangeHandler: nameChangeHandler,
        inputBlurHandler: nameBlurHandler,
        reset: resetNameInput,
      } = useInput((value) => value.trim() !== "");
    
      const [enteredEmail, setEnteredEmail] = useState("");
      const [enteredEmailTouched, setEnteredEmailTouched] = useState(false);
    
      const enteredEmailIsValid = enteredEmail.includes("@");
      const enteredEmailIsInValid = !enteredEmailIsValid && enteredEmailTouched;
    
      let formIsValid = false;
      if (enteredNameIsValid && enteredEmailIsValid) {
        formIsValid = true;
      }
    
      const emailInputChangeHandler = (event) => {
        setEnteredEmail(event.target.value);
      };
    
      const emailInputBlurHandler = (event) => {
        setEnteredEmailTouched(true);
      };
    
      //폼이 제출될 때 작동하는 함수 form onSubit으로 연결
      const formSubmissionHandler = (event) => {
        event.preventDefault();
    
        if (!enteredNameIsValid) {
          return;
        }
    
        console.log(enteredName);
    
        //custom hook에서 가져온 reset 적용
        resetNameInput();
    
        setEnteredEmail("");
        setEnteredEmailTouched(false);
      };
    
      const nameInputClasses = nameInputHasError
        ? "form-control invalid"
        : "form-control";
    
      const emailInputClasses = enteredEmailIsInValid
        ? "form-control invalid"
        : "form-control";
    
      return (
        <form onSubmit={formSubmissionHandler}>
          <div className={nameInputClasses}>
            <label htmlFor="name">Your Name</label>
            <input
              type="text"
              id="name"
              onChange={nameChangeHandler}
              onBlur={nameBlurHandler}
              value={enteredName}
            />
            {nameInputHasError && (
              <p className="error-text">Name must not be empty.</p>
            )}
          </div>
          <div className={emailInputClasses}>
            <label htmlFor="name">Your E-Mail</label>
            <input
              type="email"
              id="email"
              onChange={emailInputChangeHandler}
              onBlur={emailInputBlurHandler}
              value={enteredEmail}
            />
            {enteredEmailIsInValid && (
              <p className="error-text">Please enter a valid email.</p>
            )}
          </div>
          <div className="form-actions">
            <button disabled={!formIsValid}>Submit</button>
          </div>
        </form>
      );
    };
    
    export default SimpleInput;

    이메일에 대해 커스텀 훅 사용

    //custom hook 불러오기
    import useInput from "../hooks/use-input";
    
    const SimpleInput = (props) => {
      //useInput호출하여 반환된 결과로부터 값을 추출(객체를 반환하므로 객체 디스트럭처링으로 키를 이용해 값을 가져온다)
      //value의 키값을 value:enteredName에 할당할 수 있다 이름은 짓기나름
      //customhook에서 값을 입력해줘야 한다
      //함수를 다른 함수의 입력값으로 넣는 자바스크립트 문법
      const {
        value: enteredName,
        isValid: enteredNameIsValid,
        hasError: nameInputHasError,
        valueChangeHandler: nameChangeHandler,
        inputBlurHandler: nameBlurHandler,
        reset: resetNameInput,
      } = useInput((value) => value.trim() !== "");
    
      const {
        value: enteredEmail,
        isValid: enteredEmailIsValid,
        hasError: emailInputHasError,
        valueChangeHandler: emailChangeHandler,
        inputBlurHandler: emailBlurHandler,
        reset: resetEmailInput,
      } = useInput((value) => value.includes("@"));
    
      let formIsValid = false;
      if (enteredNameIsValid && enteredEmailIsValid) {
        formIsValid = true;
      }
    
      const formSubmissionHandler = (event) => {
        event.preventDefault();
    
        if (!enteredNameIsValid) {
          return;
        }
    
        console.log(enteredName);
    
        //custom hook에서 가져온 reset함수 적용
        resetNameInput();
        resetEmailInput();
      };
    
      const nameInputClasses = nameInputHasError
        ? "form-control invalid"
        : "form-control";
    
      //값이 유효하지 않을 경우의 email부분 style변경 ?
      const emailInputClasses = emailInputHasError
        ? "form-control invalid"
        : "form-control";
    
      return (
        <form onSubmit={formSubmissionHandler}>
          <div className={nameInputClasses}>
            <label htmlFor="name">Your Name</label>
            <input
              type="text"
              id="name"
              onChange={nameChangeHandler}
              onBlur={nameBlurHandler}
              value={enteredName}
            />
            {nameInputHasError && (
              <p className="error-text">Name must not be empty.</p>
            )}
          </div>
          <div className={emailInputClasses}>
            <label htmlFor="name">Your E-Mail</label>
            <input
              type="email"
              id="email"
              onChange={emailChangeHandler}
              onBlur={emailBlurHandler}
              value={enteredEmail}
            />
            {emailInputHasError && (
              <p className="error-text">Please enter a valid email.</p>
            )}
          </div>
          <div className="form-actions">
            <button disabled={!formIsValid}>Submit</button>
          </div>
        </form>
      );
    };
    
    export default SimpleInput;

     

Designed by Tistory.