초기 오류 코드는 다음과 같다.
import React from 'react'
import { useState } from 'react'
export default function Test() {
const [number, setNumber] = useState({
firstnumber:0,
nextnumber:0,
othernumber:0,
});
const onClick = () => {
setNumber({
firstnumber: number.firstnumber + 1,
nextnumber: number.firstnumber + 1,
othernumber: number.nextnumber + 1,
});
}
return (
<>
<div>{number.firstnumber}</div>
<div>{number.nextnumber}</div>
<div>{number.othernumber}</div>
<button onClick={onClick}>count+</button>
</>
)
}
와 같은 버튼 누르기 장난감인데
버튼을 누르면 맨 위것이 1증가하고, 아래 숫자들은 위의 숫자 +1이 된 숫자로 변경되게 만들고자 한다.
하지만, 오류 코드와 같이 작성하면 제대로 작동하지 않는다.
firstnumber: 1
nexttnumber: 1
othernumber: 1
firstnumber: 2
nexttnumber: 2
othernumber: 2
이런식으로 똑같이 증가할 뿐이다.
그래서 문제를 해결하기 위해 계속 검색하고 공부해보았다.
그래서 얻은 교훈은 다음과 같다.
기본적으로 setState는 함수처럼 여러개를 쓸 수가 없다. 만약에 여러개를 쓰게 되면 마지막에 있는 setState만 작동하게 된다.
setState로 값을 변화시키고, 그 값과 연동되어 사슬처럼 연쇄적으로 바뀌어야 하는 값이 있다면 그것은 useEffect를 활용하여 값을 바꿔주어야 한다.
개발자 커뮤니티에 질문글을 올려본 결과 여러 개발자분들이 코멘트 주신 것들을 정리해보고자 한다.
import React from 'react'
import { useState } from 'react'
export default function Test() {
const [number, setNumber] = useState({
firstnumber:0,
nextnumber:0,
othernumber:0,
});
const onClick = () => {
const firstnum = number.firstnumber;
setNumber({
firstnumber: firstnum+1,
nextnumber: firstnum+2,
othernumber: firstnum+3
});
}
return (
<>
<div>{number.firstnumber}</div>
<div>{number.nextnumber}</div>
<div>{number.othernumber}</div>
<button onClick={onClick}>count+</button>
</>
)
}
한 분이 계산을 먼저하고 setState로 한번에 적용시켜보라고 하셨다. 이렇게도 가능하다. 하지만, 내가 원했던 것은 한꺼번에 변화시키는 것이 아니고. 값의 변경를 감지하고 이로 인해 변경되어야 할 값들을 웹에 표시하는 것이기 때문에 약간 다르다.
결국 다른 분께서 코멘트 해주신 코드는
import React, { useEffect, useState } from 'react'
export default function Test() {
const [number, setNumber] = useState({
firstnumber: 0,
nextnumber: 0,
othernumber: 0,
});
useEffect(() => {
setNumber({
...number,
nextnumber: number.firstnumber + 1,
});
},[number.firstnumber]);
useEffect(() => {
setNumber({
...number,
othernumber: number.nextnumber + 1,
});
},[number.nextnumber]);
const onClick = () => {
setNumber({
...number,
firstnumber: number.firstnumber + 1,
});
}
return (
<>
<div>{number.firstnumber}</div>
<div>{number.nextnumber}</div>
<div>{number.othernumber}</div>
<button onClick={onClick}>count+</button>
</>
)
}
다음과 같은데, 이것 또한 작동을 잘한다.
그 대신 문제점이 하나 있는데?
firstnumber: 0
nexttnumber: 0
othernumber: 1
아무 버튼을 안눌렀는데도 0 0 1의 값이 표시된다.
혹시나 해서 useEffect를 아래 것부터 하나씩 주석 처리 해보니
firstnumber: 0
nexttnumber: 1
othernumber: 0
과 같이 표시 된다. useEffect의 작동 방식을 알아봐야겠다.