프로젝트를 진행 중 요일(day)을 체크박스로 선택하여 state에 담는 기능을 구현했다.
이벤트함수 내에서 setState를 사용했다.
그러나 여기서 state가 변경되는 시점을 이해하지 못하여 에러가 발생했다.
문제 상황
1. 이벤트 함수 내에서 setState를 사용했으나, 다음 줄에서 여전히 state가 변경되지 않음
2. 이벤트 함수 내에서 또 다른 이벤트 함수를 사용했으나, 마찬가지로 변경전인 state를 사용하여 연산함
3. 코드
- return 문은 생략
- 수요일~일요일 정보를 담는 state와 함수는 생략
- 클릭이벤트를 통해 monHandler와 tueHandler가 먼저 실행됨
export default function CompanyMyPage () {
// 체크박스에서 선택된 요일을 배열로 담기 위한 state
const [day, setDay] = useState([])
// 선택된 각 요일을 나타내는 state
const [mon, setMon] = useState([])
const [tue, setTue] = useState([])
// 각 요일의 체크 여부
const [monChecked, setMonChecked] = useState(false)
const [tueChecked, setTueChecked] = useState(false)
// 체크된 요일을 day state에 모아주는 핸들러
const dayHandler = () => {
setDay([...mon, ...tue, ...wed, ...thu, ...fri, ...sat, ...sun])
}
// 클릭을 통해 월요일 정보를 mon state 에 추가하거나 빼는 핸들러
const monHandler = () => {
setMonChecked(!monChecked)
if(monChecked) { // 위 setMonChecked가 있지만 monChecked는 아직 변경되지 않음
setMon(["월"])
} else {
setMon([])
}
dayHandler() // 위에 setMon이 있지만 아직 mon state가 변경되지 않음
}
// 클릭을 통해 화요일 정보를 tue state 에 추가하거나 빼는 핸들러
const tueHandler = () => {
setTueChecked(!tueChecked)
if(tueChecked) { // 위 settueChecked가 있지만 tueChecked는 아직 변경되지 않음
setTue(["화"])
} else {
setTue([])
}
dayHandler() // 위에 setTue이 있지만 아직 tue state가 변경되지 않음
}
return (
)
}
원인
1. 실행 순서를 확인하니, monHandler 함수 내의 연산이 다 끝난 이후에 setMon을 통해 mon state가 변경됨
2. monHandler 내의 이벤트 함수인 dayHandler 또한 mon state가 변경되기 전에 실행됨
3. 이벤트함수 내의 setState는 해당 함수가 실행된 이후에 적용되어, 함수 내부의 연산은 setState의 영향을 받지 않음
해결방안
1. state 변경 전이므로, if 조건문 내부의 state에 '!'를 붙여 의도된 조건문이 발동되게 하기
2. 첫번째 이벤트 함수가 끝난 후에 두번째 이벤트 함수가 실행되도록, useEffect로 두번째 이벤트 함수 실행하기
3. 이 useEffect의 발동 조건은 첫번째 이벤트 함수를 통해 변경되는 state가 되어야 함
export default function CompanyMyPage () {
// 체크박스에서 선택된 요일을 배열로 담기 위한 state
const [day, setDay] = useState([])
// 선택된 요일을 나타내는 state
const [mon, setMon] = useState([])
const [tue, setTue] = useState([])
// 각 요일의 체크 여부
const [monChecked, setMonChecked] = useState(false)
const [tueChecked, setTueChecked] = useState(false)
// 체크된 요일을 day state에 모아주는 핸들러
const dayHandler = () => {
setDay([...mon, ...tue, ...wed, ...thu, ...fri, ...sat, ...sun])
}
// 클릭을 통해 월요일 정보를 mon state 에 추가하거나 빼는 핸들러
const monHandler = () => {
if(!monChecked) { // setMonChecked를 통해 변경되기 전인 초기 state를 조건으로 사용
setMon(["월"])
} else {
setMon([])
}
setMonChecked(!monChecked)
}
// 클릭을 통해 화요일 정보를 tue state 에 추가하거나 빼는 핸들러
const tueHandler = () => {
if(!tueChecked) { // setTueChecked를 통해 변경되기 전인 초기 state를 조건으로 사용
setTue(["화"])
} else {
setTue([])
}
setTueChecked(!tueChecked)
}
// 요일 state가 변경 이후에 dayHandler를 실행
useEffect(() => {
dayHandler()
}, [mon, tue, wed, thu, fri, sat, sun]) // 변경된 요일 state를 실행 조건으로 설정
return (
)
}
반응형
'프로그래밍 > 웹 개발' 카테고리의 다른 글
[Axios/Fetch] 함수 내에서 AJAX 요청으로 받은 데이터를 리턴하기? (0) | 2021.11.09 |
---|---|
[React] 이벤트 함수에 매개변수 전달 (에러핸들링) (0) | 2021.11.01 |
[이벤트 함수] button 태그와 onClick/onSubmit (에러핸들링) (0) | 2021.10.18 |
[Axios] get 요청 시 Query Params 보내기 (에러핸들링) (0) | 2021.10.07 |
[node.js + React] 쿠키와 토큰을 활용해 로그인 기능 구현 (0) | 2021.09.11 |
댓글