[React] 여러 개의 input 상태 관리하기(useState에 객체 넣기)

2021. 4. 19. 18:28Front-end/React

728x90
반응형

🍈이번 시간에는 input이 여러 개일 때 상태를 관리하는 방법에 대해서 알아보겠다.

function InputSample(){

    const onChange = (event) => {

    };

    const handleReset = () => {

    };

    return (

        <div>

            <input placeholder="이름"/>

            <input placeholder="닉네임"/>

            <button onClick={handleReset}>초기화</button>

            <div>

                <b>값: </b>

                이름 (닉네임)

            </div>

        </div>

    )

}

위와 같이 InputSample 컴포넌트를 작성한다.

 

이렇게 보인다. 일단 지금은 값에 해당하는 이름 (닉네임) 을 수동으로 작성해 주었다.

 

🍈 좋지 않은 방법

input이 이렇게 여러 개 되었을 때는 단순히 useState를 여러 번 사용하여 onChange도 여러 개 만들고, 그렇게 구현을 할 수도 있는데 그 방법은 좋은 방법은 아니다.

 

🍈 좋은 방법 - useState가 객체를 관리하도록 하기

더 좋은 방법은, useState가 객체를 관리하도록 하는 것이다.

우리 예제에서는, input에 name이라는 props를 설정하고, 이벤트가 발생할 때 이 값을 참조하도록 할 것이다.

지난 시간엔 useState에서 기존에는 그냥 문자열 값을 관리하게 했는데 이제는 문자열이 아니라 여러 개의 문자열을 가지고 있는 객체형을 관리하도록 해주어야 한다.

 

const [inputs, setInputs] = useState({

        name: '',

        nickname: ''

    });

const {name , nickname} = inputs;

이렇게 useState 안에 객체를 넣어서, name과 nickname을 설정한다.

그리고 이 값은 inputs안에 들어가 있다.

그리고 name과 nickname을 쉽게 사용할 수 있도록 비구조화 할당을 통해 추출해준다.

 

 

  return (

        <div>

            <input name="name" placeholder="이름" onChange={onChange}/>

            <input name="nickname" placeholder="닉네임" onChange={onChange}/>

            <button onClick={handleReset}>초기화</button>

            <div>

                <b>값: </b>

                이름 (닉네임)

            </div>

        </div>

    )

그리고 return 부분에는 다음과 같이 수정해본다.

input의 name으로 각각 name과 nickname을 주었다.

 

 const onChange = (event) => {

        console.log(event.target.name);

    };

그리고 onChange 함수에서 다음과 같이 작성해주면, onChange 이벤트가 발생할 때마다 발생하는 타겟의 name 속성이 받아지고 있는 것을 확인할 수 있다.

 

const onChange = (event) => {

        const { name, value } = event.target;

        setInputs({

            ...inputs,

            [name]: value,

        });

    };

onChange 함수에서 event.target.name과 event.target.value를 편하게 작성하기 위해 비구조화할당으로 name과 value로 해준다.

그리고 이제 setInputs 함수를 작성하면 되는데, 이 때 기존의 inputs 객체를 복사한뒤 name이라는 키를 가진 값을 value로 설정한다는 의미이다.

 

💥리액트 상태(state)에서 객체를 수정해야할 때에는 inputs[name] = value로 직접 수정하면 안된다. 기존의 객체를 꼭 복사해주고 특정 값만 덮어씌운 상태로 설정해주어야 한다.

 

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

여기서 사용한 … 문법은 스프레드 문법이다. 객체의 내용을 모두 "펼쳐서" 기존 객체를 복사해준다.

이러한 작업을 "불변성을 지킨다" 라고 한다. 불변성을 지켜주어야만 리액트 컴포넌트에서 상태가 업데이트 되었음을 감지할 수 있고 이에 따라 필요한 리렌더링이 진행된다.

추가적으로, 리액트에서는 불변성을 지켜주어야만 컴포넌트 업데이트 성능 최적화를 할 수 있다. 컴포넌트 최적화에 대해서는 나중에 더 자세히 알아보겠다.

 

⭐⭐⭐지금은 리액트에서 객체를 업데이트 해야할 때는 기존 객체를 직접 수정하면 안되고, 기존의 상태를 꼭 복사하고 나서, 특정 값을 덮어씌운 상태로 설정해주어야 한다는 것만 기억하기!

728x90
반응형