State와 변수
import { useState } from 'react';
import './App.css';
function App(){
let [post, setPost] = useState('포스트명');
return (
<div className="App">
<div className="nav">
<h4>Blog</h4>
</div>
<div className="list">
<h4>{ post }</h4>
<p>2월 17일 발행</p>
</div>
</div>
)
}
- React에서는 자료를 보관해서 사용할 때 변수 이외에 State를 사용할 수 있다
- State는 변수와 다르게 값이 변하였을 때 state를 사용한 html 값을 자동으로 재렌더링 해준다(JS는 변수 값이 변했을 때 html 내용도 변경해주어야 한다는 코드를 별도로 작성해야 함) > 따라서 자주 데이터 변경이 예상되고 UI에 자동 반영이 필요한 요소는 State에 저장해 사용하면 좋다
- State 사용: let [변수명, 변경함수명] = useState('변수값')
- (참고) Distructuring 문법: let [a, b] = [1, 2]라고 선언할 경우 a=1, b=2를 할당해주는 문법이다
state 변경
let [like, setLike] = useState(0);
return (
<h4><span onClick={() => {setLike(like + 1)}}>👍</span>{ like }</h4>
)
}
- state 값을 변경하기 위해서는 setState 함수를 이용해 변경해야 UI에 반영될 수 있다(state 값을 변수처럼 변경은 가능하나 UI 반영은 안된다)
- useState 를 활용해 엘리먼트 클릭 시 변하는 데이터 값을 바로 UI에 반영(재랜더링)되도록 할 수 있다
- (참고) setState 함수는 비동기 함수기 때문에 늦게 처리(비동기 처리)된다
state array 변경
function App(){
let [arr, setArr] = useState([1,2,3]);
return (
<button onClick={() => {setArr([2,2,3])}}>btn</button>
)
}
- 위와 같이 state array 자료형을 변경할 때는 전체 array를 다시 선언해주어 변경할 수 있다
- 다만 이 방법은 array 크기가 클 경우 사용이 어렵고, 확장성이 없다
function App(){
let [arr, setArr] = useState([1,2,3]);
return (
<button onClick={() => {
arr[0] = 2;
setArr(arr);
}}>btn</button>
)
}
- 위와 같이 특정 인덱스만 변경 후 setState 함수를 통해 업데이트 해줄 수 있다
- 다만 array 원본을 훼손시키는 방법이므로 위험 요소가 높다
function App(){
let [arr, setArr] = useState([1,2,3]);
return (
<button onClick={() => {
let copy = [...arr];
copy[0] = 2;
setArr(copy);
}}>btn</button>
)
}
- 원본을 훼손시키지 않고 복사본을 만들어 값을 변경, state 변경해주는 방법으로 가장 안전하고 확장성이 높다
- ...arr 은 spread operator라는 문법으로 array를 해체시켜준다, spread operator로 해체 후 다시 []를 만들어주는 이유는 아래 setState 동작 원리를 통해 이해할 수 있다
setState 동작 원리
function App(){
let [arr, setArr] = useState([1,2,3]);
return (
<button onClick={() => {
let copy = arr;
copy[0] = 2;
setArr(copy);
}}>btn</button>
)
}
- 위처럼 코드를 작성하면 setState 함수가 state 변경을 해주지 않는다
- setState 함수가 state를 변경시키는 전제 조건이 있는데, 이는 기존 state와 변경할 state를 비교했을 때 '같지 않을' 경우에만 변경해주기 때문이다
- copy = arr 을 할 경우에는 arr 값이 저장된 RAM 주소만 카피하기 때문에 setState가 copy == arr 비교했을 때에는 같은 변수라고 판단하게 된다
- console.log(copy == arr) > true 가 나온다
- array, object 등이 위와 같은 성질을 가진 자료형이며, 자세한 내용은 javascript reference data type을 참고할 수 있다
- 이를 방지하기 위해 [...arr] 로 카피할 경우 데이터를 새로운 주소에 할당하게 되어 setState에서 변경이 가능해진다, 이를 shallow copy or deep copy 라고 한다