이번엔 inputState를 관리해보겠다.
input에 값을 입력하면 그 value가 그대로 출력되는 형식으로 만들어보겠다.
<InputSample.js>
import React,{useState} from 'react'
function InputSample() {
const [text,setText] = useState("");
const onReset = ()=>{
setText("");
}
const onChange = (e)=>{
setText(e.target.value);
}
return (
<div>
<input onChange={onChange} value={text}/>
<button onClick={onReset}>reset</button>
<div>
<b>score :{text} </b>
</div>
</div>
)
}
export default InputSample
useState가 text의 값 변경을 해주고
input 하나와 button하나 그리고 값을 보여줄 부분을 작성한다.
button의 onClick이벤트에는 setText("")를 설정해주어 클릭시 text를 공백으로 만들어 주는 역할을 부여했으며
input에는 onChange 이벤트를 부여했는데, 이벤트에 등록하는 함수는 'e'라는 객체를 파라메터로 사용할 수 있다.
이 e라는 객체의 e.target은 이벤트가 발생한 dom
따라서 onChange = (e) => 는 input 태그에 등록되있으므로 e.target은 input태그가 된다.
e.target.value는 input태그의 value가 된다.
여러개의 input은 어떻게 관리를할까?
inputSample.js를 이렇게 바꿔보겠다.
import React, { useState } from 'react';
function InputSample() {
const [inputs, setInputs] = useState({
name: '',
nickname: ''
});
const { name, nickname } = inputs; // 비구조화 할당을 통해 값 추출 (변수name과 nickname에 객체 input의 속성값인 name,nickname을 집어넣음)
const onChange = (e) => {
console.log(e.target);
const { value, name } = e.target; // 위와 마찬가지로 e.target(onchange 이벤트를 하는 input)의 속성값을 value와 name이라는 새로운 변수에 넣음
console.log(value);
console.log(name);
console.log(inputs);
setInputs({
...inputs, // 기존의 input 객체를 복사한 뒤
[name]:value
// 객체의 속성값에 값을 할당할때 동적인 키값으로 값을 할당할때 대괄호를 써줌
//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;
보통 여러개의 input이 있을 경우 input에 name을 설정하여 이벤트가 발생했을때
이 name값을 참조하는 것이다.
공부하면서 헷갈린 코드들을 하나씩 써보겠다.
const { name, nickname } = inputs;
비구조화 할당을 통해 name과 nickname이란 전역변수에 inputs의 속성값을 넣어준 것이다.
이 변수는 jsx에서의 {name},{nickname}으로 사용되어 값을 화면에 보여지게 하는 역할을 할 것이다.
const animal = {
cat2: 'CAT',
dog2: 'DOG',
tiger2: 'TIGER'
};
const { cat2, dog2, tiger2 } = animal;
console.log(cat2);//CAT
console.log(dog2);//DOG
console.log(tiger2);//TIGER
비구조화 할당의 예시이다.
const { value, name } = e.target;
e.target은 현재 이벤트중인 input을 나타내며
해당 input의 value와 name값을 value,name이라는 함수 내 변수에 삽입하는 것이다.
input을 객체로 생각하면 편하다.
이런식이면 value에 12 name에 nickname이 들어가게 된다.
리액트에서 객체를 수정할 때는
inputs[name]=value;
이런 식으로 직접적으로 수정하면 안된다.
setInputs({
...inputs,
[name]:value
});
이런식으로 새로운 객체를 복사해준 뒤 해당 객체를 수정해야한다.
...inputs를 통해 기존의 inputs를 복사해준 뒤 inputs의 name이라는 속성값의 값을 value로 바꿔주는 것이다.
이러한 작업을 '불변성을 지킨다' 라고 한다.
불변성을 지켜줘야만 리액트 컴포넌트에서 상태가 업데이트가 됬음을 감지할 수 있고 이에 따라 필요한 리렌더링이 진행된다.
* 리액트에서 객체를 업데이트 할 떄는 기존 객체를 직접 수정하면 안되고, 새로운 객체를 만들어서 그 객체에 변화를 주어야 한다.