본문 바로가기
프로그래밍/웹 개발

[React] setTimeout 내부 setState 사용 후 useEffect 동작 안 되는 에러

by 제이콥J 2021. 11. 11.

setTimeout 내에서 setState로 state를 변경시킨 후 useEffect를 실행시키는 코드를 구현했다.

그런데 setState가 실행되어도 useEffect가 실행되지 않았다.

 

원인

- setState는 비동기적으로 state를 변경시킴

- 앞에서 실행된 setState로 인해, 뒤에서 실행된 setState는 state를 바꾸지 못하므로 useEffect 실행 안 됨 

- 반복문 내에 setState를 사용해도 데이터가 축적되지 않는 것과 같은 원리

 

const [state, setState] = useState(false)

const createCareer = () => {
  axios
    .post(
      `${process.env.REACT_APP_SERVER_URL}/career`,
      { jobSeekerId }
    )
    .then((res) => {
      setState(!state)  // setState가 사용되어 state가 false에서 true로 바뀜
      setTimeout(()=>{
        axios.delete(`${process.env.REACT_APP_SERVER_URL}/career/${res.data.id}`)
        .then((res)=>{
          setState(!state)  // state는 여전히 초기값인 false 이며, setState를 통해 true 로 바뀜
        })
      }, 300000)
    })
};

useEffect(() => {
  함수
}, [state])
// 첫번째 setState에 의해 useEffect가 실행되지만, 
// 두번째 setState는 state를 바꾸지 못하므로 useEffect 실행 안 됨

 

해결방안

1. 두 번째 setState에는 다른 값을 넣어주기

 

const [state, setState] = useState(false)

const createCareer = () => {
  axios
    .post(
      `${process.env.REACT_APP_SERVER_URL}/career`,
      { jobSeekerId }
    )
    .then((res) => {
      setState(!state)  // setState 사용을 통해 useEffect 실행
      setTimeout(()=>{
        axios.delete(`${process.env.REACT_APP_SERVER_URL}/career/${res.data.id}`)
        .then((res)=>{
          setState(!!state)  // setState 안에 !!state를 넣으면 state가 변경되어 useEffect 실행됨
        })
      }, 300000)
    })
};

useEffect(() => {
  함수
}, [state])

 

 

2. 다른 hook을  선언하여 사용하기

 

const [state, setState] = useState(false)
const [eventStatus, setEventStatus] = useState(false)

const createCareer = () => {
  axios
    .post(
      `${process.env.REACT_APP_SERVER_URL}/career`,
      { jobSeekerId }
    )
    .then((res) => {
      setState(!state)  // setState 사용을 통해 useEffect 실행
      setTimeout(()=>{
        axios.delete(`${process.env.REACT_APP_SERVER_URL}/career/${res.data.id}`)
        .then((res)=>{
          setEventStatus(!eventStatus)  // setEventStatus 사용을 통해 useEffect 실행
        })
      }, 300000)
    })
};

useEffect(() => {
  함수
}, [state, eventStatus])

 

 

 

 

 

반응형

댓글