본문 바로가기

공부기록/[강의노트] Udemy React 완벽가이드 201~300

# 206 [udemy React 완벽 가이드 노트] Input value 가져오기 두가지 방법 (상황에 따른 선택방법) / 두가지 방법에 따른 유효성 검사하기

여기에는 두 가지 방법이 있다. 

1. key stroke마다 값들을 state에 저장하기 
2. 사용자가 값을 모두 입력했을 때 입력값을 가져오기 

 

 

방법 1. 

const SimpleInput = props => {

  const [enteredName, setEnteredName] = useState("");

  const nameInputChangeHandler = event => {
    setEnteredName(event.target.value);
  };
  
  const formSubmissionHandler = event => {
    event.preventDefault();
    console.log(enteredName);
    setEnteredName("");
  };
  
    return (
    <form onSubmit={formSubmissionHandler}>
      <div className="form-control">
        <label htmlFor="name">Your Name</label>
        <input
          type="text"
          id="name"
          onChange={nameInputChangeHandler}
          value={enteredName}
        />
      </div>
      <div className="form-actions">
        <button>Submit</button>
      </div>
    </form>
  );
};

 

 

방법2.

const SimpleInput = props => {
  const nameInputRef = useRef();
  const formSubmissionHandler = event => {
    event.preventDefault();
    const enteredValue = nameInputRef.current.value;
    console.log(enteredValue);
    
    nameInputRef.current.value = '';
  };
  
    return (
    <form onSubmit={formSubmissionHandler}>
      <div className="form-control">
        <label htmlFor="name">Your Name</label>
        <input
          ref={nameInputRef}
          type="text"
          id="name"
        />
      </div>
      <div className="form-actions">
        <button>Submit</button>
      </div>
    </form>
  );
};

 

 

 

 

두가지 방법 중 어떤것을 선택할까?

 

입력된 값으로 하고자 하는 일에 따라 다르다.

 

1. 폼이 제출되었을 때 한 번만 필요할 때

그 때는 모든 키스트록 마다 상태를 업데이트 할 필요가 없다. 

ref가 나을 것이다. 

 

2. 즉각적 유효성 검증이 필요할 때 
3. 입력값을 초기화 하고 싶을 때

state가 필요할 것이다. 

 

3.입력값을 초기화 하는 것은 useRef로도 가능한 방법이지만, 

직접 바닐라 자바스크립트로 DOM에 접근하여 변경하는 일이기 때문에 

지양해야 하는 일이다.  

 

 

 

 

유효성 검사하기

 

1. 입력란이 공란일 때 폼을 제출할 수 없게 하기

  

  클라이언트 사이드 유효성 검증 (브라우저에서 유효성 검증)

 

           장점 : 사용자 경험 측면에서 빠른 반응을 할 수 있어 좋다. 

 

           단점 : 그러나 브라우저에 있는 코드는 사용자에 의해 변경될 수 있으므로

                     입력값들이 서버에서도 검증되어야 한다. 

                     source 에서 자바스크립트 코드를 편집할 수 있다. 

                     보안 측면에서는 사용할 수 없는 것이다. 

 

           방법 : if 체크 하기 

 

 const formSubmissionHandler = event => {
    event.preventDefault();

    if (enteredName.trim() === "") {
      return;
    }

 

error 메시지를 보이게 해보자.

 

state를 만들어서 상태에 따라 error메시지를 띄운다. 

 

  const [enteredNameIsValid, setEnteredNameIsValid] = useState(true);

...

  const formSubmissionHandler = event => {
    event.preventDefault();

    if (enteredName.trim() === "") {
      setEnteredNameIsValid(false);
      return;
    }

    setEnteredNameIsValid(true);
    console.log(enteredName);
return (
    <form onSubmit={formSubmissionHandler}>
      <div className={nameInputClasses}>
        <label htmlFor="name">Your Name</label>
        <input
          ref={nameInputRef}
          type="text"
          id="name"
          onChange={nameInputChangeHandler}
        />
        {!enteredNameIsValid && (
          <p className="error-text">Name must not be empty</p>
        )}
      </div>
      )

만약 빈칸일 때는 return 하기 전에 setEnteredNameIsValid를 false로 바꾼다. 

빈칸이 아니라면 계속 아래 코드가 실행될 것이므로 

아래에다가는 setEnteredNameIsValid를 true로 바꿔준다.

 

return 하는 JSX코드에서는 !enteredNameIsValid 라면 <p><p>태그 안에 문구를 넣어 

렌더링해주자. 

 

 

문제점

 

이 input값에 아무것도 적지 않았는데도 enteredNameIsValid 값은 기본적으로 true다 

에러메시지가 처음에 보이지 않게 하기 위한 약간의 트릭인데, 

enteredNameIsValid에 의존한 useEffect를 사용할 경우와 같이 

실제 불리언 값을 이용하고자 할 때 

그 값은 실제 true가 아니기 때문에 문제가 될 여지가 있다. 

 

useEffect를 사용하지 않더라도 처음부터 enteredNameIsValid 값이 true인 것은

실제와 차이가 있어 별로다. 

 

 

보완

  const [enteredNameTouched, setEnteredNameTouched] = useState(false);

enteredNameTouched state를 추가하여  

form이 submit되면 true로 변경해주자. 

 

 const formSubmissionHandler = event => {
    event.preventDefault();

    setEnteredNameTouched(true);

 

그리고 이 값을 사용해 

 

nameInputIsValid 변수를 만들어주고

 

const nameInputIsInvalid = !enteredNameIsValid && enteredNameTouched;

위의 조건문이 모두 true 일 때만 에러메시지를 렌더링 해주는 것으로 바꾼다. 

 

        {nameInputIsInvalid && (
          <p className="error-text">Name must not be empty</p>
        )}

 

 

그러면 좀더 실제에 가까운 상태로 만들어졌다.

input 필드를 입력하지 않은 상태에서도 error메시지가 뜨지 않고, 

아무것도 입력하지 않은 채 submit을 하게 되면 그제서야 error메시지가 뜬다.