React input 기본값 - React input gibongabs

input 상태 관리하기

이번에는 리액트에서 input상태를 어떻게 관리하는지 알아보도록 하자.

InputSample.js

import React from "react";

function InputSample() {
  return (
    <div>
      <input />
      <button>초기화</button>
      <div>
        <b>값: </b>
        어쩌고저쩌고...
      </div>
    </div>
  );
}

export default InputSample;
React input 기본값 - React input gibongabs
InputSamle.js의 결과

다음과 같이 입력한 것이 '값:'에 표시되고 초기화를 누르면 입력창이 비워지는 예제를 통해 알아보자.

 이전에는 onClick이라는 이벤트를 관리했는데 이번에는 input에서 onChange라는 이벤트를 관리해 볼 것이다.

import React from "react";

function InputSample() {
  const onChange = (e) => {
    console.log(e.target.value);
  };
  return (
    <div>
      <input onChange={onChange} />
      <button>초기화</button>
      <div>
        <b>값: </b>
        어쩌고저쩌고...
      </div>
    </div>
  );
}

export default InputSample;

'onChange'라는 함수를 만들어 input의 onChange이벤트에 등록해준다. 4번 줄의 onChange 함수에서 이벤트 객체 e가 의미하는 것은 만약 input에서 수정 이벤트가 발생했을 때 그 이벤트에 대한 내용이 이벤트 객체 e에 저장되어 사용할 수 있게 되는 것이다. e.target이라는 값은 현재 input(이벤트가 발생한 DOM)에 대한 정보를 가지고 있다. 그래서 현재 

DOM이 갖고 있는 값을 알고 싶으면 'e.target.value'를 통해 갖고 올 수 있다. 

React input 기본값 - React input gibongabs
위 코드에 대한 결과는 다음과 같다.

이제 입력한 값을 가져오는 방법을 알았으니 표시되도록 만들어보자. 여기서 전에 공부했던 useState를 사용한다. 

InputSample.js

import React, { useState } from "react";

function InputSample() {
  const [text, setText] = useState("");
  const onChange = (e) => {
    setText(e.target.value);
  };

  const onReset = () => {
    setText("");
  };
  return (
    <div>
      <input onChange={onChange} value={text} />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값: </b>
        {text}
      </div>
    </div>
  );
}

export default InputSample;
React input 기본값 - React input gibongabs
입력한 값이 표시되고 초기화를 누르면 비워진다.

console.log 대신 setText로 바꾸어 주었고 input 태그에 value 값을 추가해 주었다. value값을 설정해 주어야 나중에 

초기화 버튼을 눌러 input을 비워지게 하는 것이 가능하다. onReset 함수를 만들어 초기화 버튼도 구현했다.

여기서 input 태그의 value값을 설정해주지 않으면, 초기화 버튼을 눌러도 input이 비워지지 않는다. 다른 곳에서도 

setText를 사용해서 text 값이 바뀌었을 때  input에 있는 값이 바뀌게 하려면 위 코드처럼 value={text}와 같이

넣어주는 것이 중요하다.

여러 개의 input상태 관리하기

이번에는 input이 여러 개가 되었을 때 어떻게 해야 하는지 알아보자. input이 여러 개가 되었을 때 단순히 useState를 

여러 개 사용하고, onChage도 여러 개 사용하는 방법을 쓸 수는 있겠지만 이 방법이 가장 좋은 방법은 아니다. 

좋은 방법은 input에 name이라는 값을 설정하고 이벤트가 발생했을 때 이 값을 참조하는 것이다. 그리고 useState에선 기존의 문자열이 아니라 여러 개의 문자열을 가진 객체 형태의 상태를 관리해야 한다.

InputSample.js

import React, { useState } from "react";

function InputSample() {
  const [inputs, setInputs] = useState({
    name: "",
    nickname: "",
  });
  const { name, nickname } = inputs;
  const onChange = (e) => {
    const { name, value } = e.target;

    setInputs({
      ...inputs,
      [name]: value,
    });
  };

  const onReset = () => {
    setInputs({
      name: "",
      nickname: "",
    });
  };
  return (
    <div>
      <input 
      	name="name" 
        placeholder="이름" 
        onChange={onChange} 
        value={name} 
      />
      <input
        name="nickname"
        placeholder="닉네임"
        onChange={onChange}
        value={nickname}
      />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값: </b>
        {name} ({nickname})
      </div>
    </div>
  );
}

export default InputSample;
React input 기본값 - React input gibongabs
InputSample 컴포넌트의 결과

다음 코드를 살펴보자, 먼저 useState에서 객체 형태의 상태를 관리할 수 있게 선언해주었다. 각 name, nickname의 

초기값은 공백이다.  그리고 비구조화 할당으로 name과 nickname을 추출해 주었다.

onChange 함수에서는 먼저 e.target.name과 e.target.value를 간략하게 name, value로 사용하기 위해서 비구조화 

할당을 사용한다. 이 코드에서는 e.target.name에 'name', 'nickname'이 들어가고 e.target.value에는 사용자가 입력해준 

손흥민과 Sonny가 들어간다.

그다음으로 setInputs()을 보면 spread 문법을 사용해서 기존의 상태를 한 번 복사하고 거기에다 특정 값을 덮어 씌우고 그것을 새로운 상태로 설정해주고 있다. 이렇게 해주는 것을 '불변성을 지킨다'라고 한다.

불변성을 지켜주어야만 리액트 컴포넌트에서 상태가 업데이트됐음을 감지할 수 있고 이에 따라 필요한 렌더링이

발생하게 된다. 만약 'inputs[name] = value;'와 같이 작성하게 되면 input값을 수정해도 변화가 발생하지 않게 된다. 

그렇기 때문에 이 부분은 꼭 알아두어야 한다.

객체 상태를 업데이트 할때에는 '...' spread 문법을 사용해서 객체를 복사하고 나서 특정 값을 덮어 씌워 상태를

업데이트해줘야 한다는 것을 기억하자.

다음으로 각 input에서 name을 설정해 준 것을 확인할 수 있다. name을 설정함으로써 각 input을 쉽게 컨트롤 할 수 

있다. 여러 개의 input을 관리해야 할 때는 위 코드 처럼 name 값을 설정해주는 것을 기억하자.

불변성을 지키는 것은 나중에 배열 상태를 관리하게 될 때에도 마찬가지이고, 불변성을 지켜줘야만 컴포넌트 업데이트 성능을 최적화할 수 있다. 이것에 대해서는 나중에 자세하게 알아보자.