0. 한줄평
- 자주 바뀔것 같은 데이터들은 state에 저장했다가 html에 {데이터바인딩} 해놓자
- 바뀌지 않는 것들은 state로 굳이 저장할 필요가 없다.
- state는 상품명,글제목, 가격 이런것처럼 자주 변할 것 같은 데이터들을 저장하는게 좋다.
1. 리액트의 state란?
- 컴포넌트가 가질수 있는 상태
ex) 시계라는 컴포넌트가 있다면 time 이라는 state를 가질 수 있음
2. useState
- useState를 사용하기 전에 코드창 상단에 아래와 같이 import를 해야한다.
import {useState} from 'react'
🔸useState란?
- 우리의 컴포넌트의 상태를 간편하게 생성하고, 업데이트 시키게 해주는 도구
ex) time = 6시 (시간의 상태는 계속해서 바뀐다. 바뀌는건 업데이트가 필요하다)
- 즉, 사용자 인터렉션에 따라 상태의 값이 바뀌어야할때 필요한 것
- 변동사항이 생기면 state를 쓰는 html도 자동으로 재 랜더링 해준다.
state 와 setState의 이름은 마음대로 바꿔도 상관없다.
하지만, 상태변경함수(setState)는 set+state명 으로 주로 짓는다
ex) let [name,setName] = useState('선은혜')
let [age,setAge] = useState(28)
🔸useState 사용방법 예시코드
- 배열구조분해 문법을 알면 아래 코드가 더 쉬워질것이다.
//state: 우리의 현재 상태값은 state라는 변수에 들어있음(변수명이라고 생각하자)
//setState : 우리가 state를 변경시켜주고싶을 때는 setState함수 이용
const [state,setState] = useState(초기값);
ex) 시계 컴포넌트 안에 time이라는 state가 생기고 초기값은 5라는 뜻
초기값을 변경시켜주고 싶으면 setTime함수를 쓰고 인자로는 변경될 값을 넣어주면 된다.
즉, setTime() 함수는 소괄호 안에 넣은 인자 값으로 state(상태값)를 바꿔준다.
const [time,setTime] = useState(5);
// time = 5
// setTime(6); 이렇게 쓰면 time = 6 으로 바뀐다.
즉, setTime 함수를 써서, state를 변경하면 해당 컴포넌트는 화면에 다시 렌더링이 된다.
time state가 변경될때마다, 화면이 업데이트 된다
2-1) setState 즉, 상태변경함수의 인자에 콜백함수를 사용하면?
setState((이전상태값) => {
return(새로운 state 지정)
});
setState 함수의 인자에 콜백함수를 넣어주게 되면
1. 콜백함수의 인자는 이전 상태값을 가지게 된다.
2. 콜백함수의 return 값에는 새로운 state를 지정 할 수있다.
예제코드 1)
update버튼을 누르면 시간이 1시간씩 추가되는 useState 기능을 구현해보자
time state를 setTime 함수를 통해서 state를 업데이트 해줄수있다.
setTime 함수를 이용해서, state를 업데이트 시켜주게 되면 이 컴포넌트는 브라우저 상에서 다시 그려지게 된다.
(= 다시 렌더링이 된다) 매번 컴포넌트가 다시 렌더링 될때마다 {time}에는 업데이트된 state가 들어있다.
Hello.js 파일을 만들어서 App 함수에 컴포넌트화 해줬다.
setTime() 안에 들어간 인자로 state값이 변경되는 걸 뜻한다. 아래에서는 setTime(time+1) 로 변경되었으니
초기값 1 + 1 해서 2가 되는걸 알수있다. time 이 2 로 변경되었으니 다음 버튼을 또 클릭하면 2+1
또 클릭하면 3+1 이런식으로 해서 상태값이 변경되는 것을 알수있다.
import {useState} from 'react'
function Hello() {
let [time,setTime] = useState(1)
const handleClick =()=>{
setTime(time+1)
}
return(
<div>
<span>현재 시각 :{time}시</span>
<button onClick={handleClick}>Update</button>
</div>
)
}
export default Hello;
혹은 아래와 같이 표현할 수 있음
import {useState} from 'react'
function Hello() {
let [time,setTime] = useState(1)
console.log('업데이트!!')
return(
<div>
<span>현재 시각 :{time}시</span>
<button onClick={()=>{setTime(time+1)}}>Update</button>
</div>
)
}
export default Hello;
예제코드2)
버튼을 클릭하면 초기값 1시에서 +1 씩 증가하게 만들자
그런데, 12시가 넘으면 다시 1로 가게 해주자
setTime(newTime) 으로 되어있으니 newTime 값으로 state값이 변경한다.
import {useState} from 'react'
function Hello() {
let [time,setTime] = useState(1)
const handleClick =()=>{
let newTime;
if (time>=12){
newTime = 1;
}else{
newTime = time+1;
}
setTime(newTime);
}
console.log('업데이트!!')
return(
<div>
<span>현재 시각 :{time}시</span>
<button onClick={handleClick}>Update</button>
</div>
)
}
export default Hello;
3. 변동사항이 생기면 state를 쓰는 html도 자동으로 재 랜더링 해준다.
- state는 html 로 자동으로 재 렌더링 해주는게 가장 key-point이다.
1) state를 쓰지 않은 예제코드
- 아래 예제코드를 보면 우리는 change 버튼을 누르면 Mike라는 이름이 Jane으로 바뀌고 Jane이면 Mike로 바뀌는 이름으로 설계해놨다.
- 그런데 state를 쓰지 않고 오로지, 변수로만 바꾸려고한다면 화면에 렌더링 되지 않는다.
- console.log(name) 을 출력했을때는 name이 Jane, Mike 자유자재로 변하는게 보이지만, 화면에 렌더링이 되지않는다.
- 따라서, 렌더링을 해주기 위해서는 자바스크립트처럼 document.getElementById('name').innerText = name;으로 해서 Dom 을 건들여줘야한다.
//Hello.js 에서 컴포넌트를 export 해서 App.js에서 import함
/*eslint-disable */
export default function Hello(){
let name = "Mike"
function changeName(){
name = name==="Mike"?'Jane':"Mike";
console.log(name);
document.getElementById('name').innerText = name;
}
return(
<div>
<h1>state</h1>
<h2 id="name">{name}</h2>
<button onClick={changeName}> Change</button>
</div>
)
}
2) state를 쓴 예제코드
/*eslint-disable */
import {useState} from 'react'
export default function Hello(){
const [name,setName] = useState('Mike');
function changeName(){
const newName = name==="Mike"?'Jane':"Mike";
setName(newName)
}
return(
<div>
<h1>state</h1>
<h2 id="name">{name}</h2>
<button onClick={changeName}> Change</button>
</div>
)
}
참고자료 : 별코딩 유튜브 https://www.youtube.com/watch?v=G3qglTF-fFI
코딩애플 수업
코딩앙마유튜브 https://www.youtube.com/watch?v=p5ZP4xzhRxk&list=PLZKTXPmaJk8J_fHAzPLH8CJ_HO_M33e7-&index=7
'프론트엔드 개발 > React' 카테고리의 다른 글
React 기초) 반복되는 html요소들을 줄이고 싶을때는 map (0) | 2022.11.22 |
---|---|
React 기초) useState 배열 상태 값 변경하는 방법(spread 문법) (1) | 2022.11.22 |
React 기초) 이벤트리스너 다는 방법 (0) | 2022.11.21 |
리액트) HTML emmet 기능, 자동 완성 안될 때 (0) | 2022.11.09 |
React) 리액트 터미널창에 WARNING 뜰 때 해결법 (0) | 2022.11.09 |