input 상태 관리하기
- input 에
onChange
를 사용하면 이벤트에 등록되는 함수에서는 이벤트 객체e
를 파라미터로 받아올 수 있다. e.target
은 이벤트가 발생한 DOM인 input DOM 을 가리킨다.e.target.value
를 조회하면 현재 input 에 입력한 value 값을 알 수 있다.- 변경되는 값은
useState
로 관리한다. - input의 상태를 관리할 때는 input 태그의 value 값도 설정해주어야 상태가 바뀌었을 때 input 내용도 업데이트 된다.
function InputSample() {
const [text, setText] = useState(''); // input 관리할 상태 생성 (기본값 공백으로 설정)
const onChange = (e) => {
setText(e.target.value); // 이벤트 발생한 input DOM에 입력한 값 조회 (value)
};
const onReset = () => { // 초기화
setText('');
};
return (
<div>
<input onChange={onChange} value={text} /> // input 태그 value 설정
<button onClick={onReset}>초기화</button>
<div>
<b>값: {text}</b>
</div>
</div>
);
}
input의 상태를 관리할 때는 input 태그의 value 값도 설정해주어야 초기화 버튼을 눌러서 상태가 바뀌었을 때도 input 내용도 업데이트 되어 비울 수 있게 된다. input 이 같이 업데이트 되지 않으면 초기화를 눌렀을 때 값은 없어지지만 input 창의 값은 비워지지 않는다.
여러개의 input 상태 관리하기
여러개의 input 을 관리할 때는 input 에 name
을 설정하고 이벤트가 발생했을 때 이 값을 참조한다.
useState 에서는 문자열이 아니라 객체 형태의 상태를 관리한다.
불변성 지키기
리액트에서 객체를 업데이트 하게 될 때에는 기존 객체를 직접 수정하면 안되고, 새로운 객체를 만들어서 새 객체에 변화를 주어야 한다. 이러한 작업을 "불변성을 지킨다" 라고 부른다.
불변성을 지켜주어야만 리액트 컴포넌트에서 상태가 업데이트 됐음을 감지할 수 있고, 이에 따라 필요한 리렌더링이 진행된다.
만약에 inputs[name] = value
처럼 기존 상태를 직접 수정하게 되면 값을 바꿔도 리렌더링 되지 않는다.
리액트에서는 불변성을 지켜주어야만 컴포넌트 업데이트 성능 최적화를 제대로 할 수 있다.
inputs[name] = value; // (X)
setInputs({
...inputs,
[name]: value
});
기존 객체 복사
spread (...) 는 객체의 내용을 모두 펼쳐서 기존 객체를 복사해준다.
기존의 inputs 의 내용(name, nickname)이 현재 스프레드의 위치로 복사되어 온다.
const nextInputs = {
...inputs,
};
여기서 특정값을 덮어씌우고 싶을 때는 다음과 같이 작성하면 된다.
nextInputs[name] = value;
InputSample.js
import React, { useState } from 'react';
function InputSample() {
const [inputs, setInputs] = useState({ // 객체상태 관리
name: '',
nickname: ''
});
const { name, nickname } = inputs; // 비구조화 할당을 통해 값 추출
const onChange = (e) => {
const { value, name } = e.target; // 우선 e.target 에서 name 과 value 를 추출
setInputs({
...inputs, // 기존의 input 객체를 복사한 뒤
[name]: value // 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;