-
React Hooks : useState() 함수Study/React 2020. 1. 4. 10:25반응형
리액트 컴포넌트에서 동적인 값을 상태(state) 라고 부른다.
사용자 인터랙션을 통해 컴포넌트의 상태값이 동적으로 바뀔 경우에는 상태를 관리하는 것이 필요하다.
React Hooks 가 나오기 이전에는 상태값을 관리하기 위해 class 기반의 클래스 컴포넌트를 작성해야했다.
클래스 컴포넌트는 간단한 상태 관리 조차도 함수형 컴포넌트에 비해 복잡하여 유지 보수가 힘들었다.
하지만 리액트 16.8 버전부터 Hooks 라는 기능이 도입되면서 함수형 컴포넌트에서도 상태를 관리할 수 있게 됐다.
Hooks 중에 useState() 함수가 있는데, 이를 통해 함수형 컴포넌트에서도 상태를 관리할 수 있다.
useState( ) 함수 사용법
Counter.js
import React, { useState } from 'react'; function Counter() { const [number, setNumber] = useState(0); const onIncrease = () => { setNumber(preNum => preNum + 1); } const onDecrease = () => { setNumber(preNum => preNum - 1); } return ( <div> <h1>{number}</h1> <button onClick={onIncrease}>+1</button> <button onClick={onDecrease}>-1</button> </div> ); } export default Counter;
import React, { useState } from 'react';
: 리액트 패키지에서 useState 함수를 불러온다.
const [number, setNumber] = useState(0);
: useState 함수를 호출하면 배열을 반환하는데,
1번째 원소 number는 현재 상태 값 변수이고, 2번째 원소 setNumber는 상태 값을 갱신해주는 Setter 함수이다.
useState 괄호 안의 값은 상태의 초기 값이다.
useState 함수는 아래와 같이 사용하면 된다.
const [상태 값 저장 변수 , 상태 값 갱신 함수] = useState(상태 초기 값);
원래 위 코드는 아래와 같지만, es6 문법 destructuring을 통해 각 원소를 추출하여 위와 같이 사용하는 것이다.
const numberState = useState(0); const number = numberState[0]; const setNumber = numberState[1];
const onIncrease = () => {
setNumber( preNum => preNum + 1) ; }
: 상태 값 갱신 함수 setNumber는 파라미터로 전달받은 preNum을 최신 상태로 설정해준다.
setNumber( number + 1)
원래 setNumber 파라미터에는 위와 같이 업데이트 할 새로운 값을 넣어주는데,
setNumber( preNum => preNum + 1)
위와 같이 기존 값을 값을 업데이트 하는 함수를 넣어 값을 업데이트 할 수도 있다.
이와 같은 함수형 업데이트는 컴포넌트를 최적화 할 때 주로 사용한다.
{number}
: 갱신된 현재 상태 값을 렌더링해준다.
useState( ) 함수로 여러 개의 상태 값 관리하기
1) input 태그 하나일 경우
InputTest.js
import React, { useState } from 'react'; function InputTest() { 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> 내용: {text}</b> </div> </div> ); } export default InputTest;
const onChange = (e) => {
setText(e.target.value); }
: 이벤트가 일어나는 타겟의 value를 text 값으로 업데이트 해준다.
const onReset = () => {
setText(''); }
: text 값을 '' 공백으로 업데이트 한다.
<input onChange={onChange} value={text} />
: input 태그에 onChange 이벤트를 등록하고 value 값으로 text 상태 값을 준다.
value 값을 설정해주지 않으면 상태가 바뀌었을 때 input 내용이 업데이트 되지 않는다.
2) input 태그 여러 개의 경우
동일한 태그가 여러 개일 경우에 useState나 onChange를 여러 개 만드는 것 보다,
각 태그에 name 값을 설정해주고 이벤트가 발생했을 때 이를 참조하여 상태 값을 관리하는 것이 좋다.
그리고 여러 개의 state 를 관리해야 하기 때문에 useState 함수는 객체 형태를 받아야 한다.
InputTest.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; 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;
const [inputs, setInputs] = useState({
name: '',
nickname: '' })
: 객체 형태로 두 input 태그의 name 속성의 초기값을 설정해준다.
const { name, nickname } = inputs;
: inputs 상태값을 디스트럭쳐링 하여 두 name 속성값을 추출해준다.
const { value, name } = e.target;
: 이벤트 타겟의 속성 value와 name을 추출해준다.
setInputs({
...inputs,
[name]: value
});
: 리액트 상태에서 객체를 수정할 때는 inputs[name] = value 와 같이 직접 수정하면 안된다.
대신 spread 문법을 사용하여 ...inputs, 기존 객체를 복사하여 새로운 객체를 만들고,
이 새로운 객체에서 상태를 업데이트 [name]: value 해줘야한다.
여기서 [name]과 같이 대괄호를 사용하는 것은 변수로서 name이 들어올 수도 있고 nickname이 들어올 수도 있다.
이렇게 기존 객체를 복사하여 새로운 객체에 업데이트 작업을 하는 것을 "불변성을 지킨다" 는 것이다.
불변성을 지켜줘야만 리액트가 컴포넌트의 상태가 업데이트 됐음을 감지할 수 있고
필요한 부분만을 리렌더링 할 수 있기 때문이다.
기존 상태를 직접 수정하는 경우 리렌더링이 되지 않는다.
반응형'Study > React' 카테고리의 다른 글
React Hooks : useEffect() 함수 (2) 2020.01.06 React Hooks : useRef() 함수 (6) 2020.01.05 React 조건부 렌더링 (0) 2020.01.03 React props : 컴포넌트에게 값 전달 (0) 2020.01.03 React 문법 : JSX (JavaScript XML) (0) 2020.01.02