[react] state 변경, react불변성

들블리셔·2022년 7월 29일
0

state 변경

let [아이템, 아이템변경] = useState(['냉면', '모밀', '초계국수']);
<h1>{아이템[0]}</h1>	// <h1>냉면</h1>

click 이벤트를 통해서 state값인 냉면을 국수로 변경하려고 한다.

  • state를 변경할 때 state가 array,object일 경우 원본을 보존하는 습관을 들이자.
  • 우선 state를 변경할 때, 기존state == 신규state 이라면 변경해주지 않는다.



잘못된 예 )

let [아이템, 아이템변경] = useState(['냉면', '모밀', '초계국수']);
<h1>{아이템[0]}</h1>	// <h1>냉면</h1>
<button onClick={ () => {
	let copy = 아이템;
    copy[0] = '국수';
    console.log(아이템 == copy) // true 반환, 기존과 신규 state가 같다 생각.
   아이템변경(아이템);
}}>텍스트 바꿀래</button>

이렇게 코드를 짜면 되겠지 하지만 변경 되지 않는다.
실제로 배열안에 첫번째 값을 냉면은 국수로 변경을 했지만
배열안에 데이터값만 변경한 것이지 아이템이라는 변수를 변경했다고 생각을 하지 않는다.


쉽게 말해 아이템이라는 변수는 배열안 값을 나타내는 화살표만 저장 한것이고, 배열 안의 값을 변경했다고 해도 화살표는 그대로이기 때문에
같다고 true를 반환 한다. 주소값이 다르다고 표현한다.


이런 이유는 리액트의 불변성과 관련이 있다. 아래 글 참고


해결방법 )

let [아이템, 아이템변경] = useState(['냉면', '모밀', '초계국수']);
<h1>{아이템[0]}</h1>	// <h1>냉면</h1>
<button onClick={ () => {
	let copy = [...아이템];	
    copy[0] = '국수';
    console.log(아이템 == copy) // false 반환, 기존과 신규 state가 같지않으므로 state 변경
   	아이템변경(아이템);
}}>텍스트 바꿀래</button>
  • button을 클릭하면 h1태그 안의 기존의 내용인 '냉면'은 '국수'로 바뀌게 된다.
  • 참조타입인 경우라서 새로운 배열을 만들고 기존의 배열은 건드리지 않는 ES6문법인 spread 연산자를 사용하면 된다.



react의 불변성

  • 불변성이란 값이나 상태를 변경할 수 없는 것을 의미한다.
  • react는 업데이트라는 개념을 가지고 있다. 리액트는 상태 업데이트를 하는 원리이기 떄문이라고 한다.
  • 값을 변경할때 기존의 값을 가져와서 바뀌는 부분만 고쳐야 한다.



let obj = {
	a: 1,
	b: 2
}
obj.a = 7;
console.log(obj)    // {a:7, b:2}

이렇게 변수 obj에 대해서 실제로 수정이 됐지만,
리액트에서는 다르다.



let obj = {
  a: 1,
  b: 2
}
obj = {
	...obj,
	a: 7
}
console.log(obj)    // {a:7, b:2}

obj라는 변수의 객체를 변경 하고 싶다면
기존의 값을 복사하고 나서 원하는 값을 바꿔주어야 한다.



원시타입과 참조타입


  • setState를 이용할 때 원시타입 경우에는 값을 바로 넣어주어도 되지만
  • 참조타입인 경우에는 새로운 객체나 배열을 생성한 후 값을 넣어주어야 한다.

// 원시타입
const [number, setNumber] = useState(0)
setNumber(7)

// 참조타입
const [info, setInfo] = useState({ name: 'kim', age: 29 })
setState({...info, name: 'nam'})





결론

  • 리액트에서는 업데이트하기 위해서 js코드처럼 수정하면 안된다.

  • 참조타입인 경우 새로운 객체나 배열을 생성한 후 값을 수정해야한다.
    (spread연산자, map, filter, slice, reduce)
    splice같은 메서드는 원본데이터를 변경하므로 X


참고한 블로그!

profile
나의 공부방

0개의 댓글