[패스트캠퍼스 수강 후기] 프론트엔드 인강 100% 환급 챌린지 21회차 미션 - 30강 React useState를 통해 컴포넌트의 바뀌는 값 관리
useState
웹에서 동적인 일이란, 사용자 인터렉션에 따라 값이 바뀌는 것을 말한다. react 16.8 이전에는 함수형 컴포넌트에서 상태를 관리할 수 없었는데 react 16.8이후 부터 Hooks를 통해 함수형 컴포넌트에서도 상태를 관리할 수 있게 되었다. useState라는 함수를 통해 상태를 관리해보자.
useState를 통해 카운터만들기
먼저 src 폴더에 Counter.js를 만들어주자.
Counter.js
import React from 'react';
function Counter(){
const onIncrease = () => {
console.log('+1');
}
const onDecrease = () => {
console.log('-1');
}
return(
<div>
<h1>0</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
)
}
export default Counter;
javascript에서는 onclick으로 소문자로 써주는데 react에서는 onClick 이렇게 카멜기법으로 써줘야 한다. 그리고 함수를 onIncrease() 이렇게 호출하면 안되고 함수 이름만 넣어주어야 한다. 이런 차이를 잘 알아두도록 하자.
자, 이제 아래와 같이 useState를 써서 버튼 클릭 시 상태값을 바꾸도록 만들어보자.
Counter.js
import React, { useState } from 'react'; //React,뒤에 useState를 선언
function Counter(){
const [number, setNumber] = useState(0); //우리가 number라는 상태를 만들건데 이 상태의 기본값은 0으로 하겠다. setNumber은 이 상태를 바꿔주겠다. 배열구조분해를 사용한 상태.
const onIncrease = () => {
setNumber(number + 1);
}
const onDecrease = () => {
setNumber(number - 1);
}
return(
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
)
}
export default Counter;
import React뒤에 콤마를 찍어주고 { useState }라는 함수를 쓸거라고 선언해준다.
그리고 컴포넌트 안에서 useState라는 함수의 값을 가져올 변수를 두개 만들어주고 useState안에는 기본값을 ()안에 선언해준다.
const [number, setNumber] = useState(0);
위 코드 중 이 부분은 배열 구조분해 형태이다. 원래대로 풀어서 쓰자면 아래와 같다.
const numberState = useState(0);
const number = numberState[0];
const setNumber = numberState[1];
이렇게 써줘도 똑같이 동작한다. useState는 배열을 반환하는데 첫번째에는 현재 값, 두번째에는 새로운 상태로 업데이트 하는 함수가 들어있다. 그래서 두번째 배열을 담아 둔 변수 setNumber안에 새로 연산할 값을 넣어주는 것이다. setNumber(number + 1)이런식으로 ..
useState의 함수형 업데이트
그리고 한가지 더 알아야 할 것이 있는데 useState를 쓸 때, 함수형 업데이트를 하는 것이다.
import React, { useState } from 'react';
function Counter(){
const [number, setNumber] = useState(0);
const onIncrease = () => {
setNumber(prevNumber => prevNumber + 1); //이부분을 이렇게 바꿔준다
}
const onDecrease = () => {
setNumber(prevNumber => prevNumber - 1); //여기도
}
return(
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
)
}
export default Counter;
기존의 number변수를 쓰지 않고 이런식으로 함수형으로 업데이트를 하는 방식인데 위 코드에서는 딱히 왜 이렇게 쓰는지 분별할수는 없지만 일단은 이렇게 함수형으로 업데이트를 할 수 있고, 이게 최적화랑 관련이 있다는 사실을 알아두자.
정리하면 setNumber는 사용하는 두가지 방법이 있다. 첫번째는 어떠한 값으로 바꿀거라는 다음 상태 값을 넣어주는 것이고 두번째는 이런 상태로 로직을 업데이트 할꺼라고 함수를 넣어줄 수도 있다는 것. 이렇게 두가지 기억해두자.
input 상태 관리하기
이번엔 인풋에 텍스트를 써넣으면 그 값을 바로 반영하도록 상태를 관리해보자.
먼저 InputSample이라는 컴포넌트를 만들어주고 아래와 같이 콘솔테스트를 해보자.
InputSample.js
import React from 'react';
function InputSample(){
const onChange = (e) => { //여기서 'e'는 이벤트 객체.
console.log(e.target.value); //이벤트 객체의 타겟의 벨류값을 가져오겠다.
}
return(
<div>
<input onChane={onChange} />
<button>초기화</button>
<div>
<b>값: </b>
하나둘셋넷다섯
</div>
</div>
)
}
export default InputSample;
먼저 변수 onChange의 event target은 onChange를 설정해준 input이 된다. 그리고 여기의 value값은 우리가 input에 써넣어주는 값이 될 것이다. 위처럼 써주고 콘솔을 보면 input에 무언가를 써넣을때마다 console에 찍히는 것을 볼 수 있을 것이다. 이제 이것을 활용해서 useState를 써먹어보자.
InputSample
import React, { useState } from 'react';
function InputSample(){
const [text, setText] = useState('');
const onChange = (e) => {
setText(e.target.value);
}
const clearText = () => {
setText('');
}
return(
<div>
<input onChange={onChange} value={text}/>
<button onClick={clearText}>초기화</button>
<div>
<b>값: </b>
{text}
</div>
</div>
)
}
export default InputSample;
여기서 nput안에 value값에 text를 넣어주는 것이 중요하다! 그걸 빼먹고서 초기화 버튼을 혼자 구현하려고 해봤는데 복잡해지더라.. 저렇게 간단하게 value안에 text만 실시간으로 호환(?)시켜주면 별다른 복잡한 절차없이 (input에 접근해서 강제로 value를 클리어 하려고 시도했음;;) setText(‘‘)만으로 클리어가 가능하다.
input이 여러개일때 상태관리하기
자 한개의 input은 간단하게 제어했다. 그럼 여러개의 input이 있을 경우 어떻게 상태를 관리할까?
InputSample.js
import React, { useState } from 'react';
function InputSample(){
const [inputs, setInputs] = useState({
name: '',
nickname: '',
}) //useState를 객체로 관리
const {name, nickname} = inputs;
const onChange = (e) => {
console.log(e.target.name);
console.log(e.target.value);
}
const clearText = () => {
}
return(
<div>
<input placeholder="이름" name="name" onChange={onChange}/>
<input placeholder="닉네임" name="nickname" onChange={onChange}/>
<button onClick={clearText}>초기화</button>
<div>
<b>값: </b>
이름 (닉네임)
</div>
</div>
)
}
export default InputSample;
일단 이렇게까지 하고 input에 입력을 하면 콘솔에 입력되고 있는 input의 name과 value가 나타나는 것을 볼 수 있다. 이제 useState를 객체로 만들어서 관리해보자.
import React, { useState } from 'react';
function InputSample(){
const [inputs, setInputs] = useState({
name: '',
nickname: '',
}) //useState를 객체로 관리
const { name, nickname } = inputs;
const onChange = (e) => {
const { name, value } = e.target; //name과 value를 변수이름 따로 만들어줌
setInputs({
...inputs, //기존의 객체 복사(불변성을 지키기위해)
[name]: value, //문자열 name이 아닌 키값을 의미하도록 []안에 씀.
});
}
const clearText = () => {
setInputs({
name:'',
nickname:''
})
}
return(
<div>
<input placeholder="이름" name="name" onChange={onChange} value={name} />
<input placeholder="닉네임" name="nickname" onChange={onChange} value={nickname} />
<button onClick={clearText}>초기화</button>
<div>
<b>값: </b>
{name} ({nickname})
</div>
</div>
)
}
export default InputSample;
여기서 기억해야할 것은 … 스프레드 문법을 사용해서 기존의 객체를 한번 복사해주고 사용해야한다는 것이다. 그래야 리액트가 기존의 객체를 기억하고 새로 업데이트 시킬 수 있다고 한다. 신기하게 잘 작동하는데 아직 복잡해서 이 영상은 몇번 더 봐야쓰겄다.
오늘은 여기까지..
시청 영상 30강 8~10까지
프론트엔드 개발 올인원 패키지 with React Online. 👉 https://bit.ly/31Cf1hp
Comments