TIL: React | useEffect 와 비동기 async/await 의 순서 보장

Lumpen·2023년 4월 17일
0

React

목록 보기
9/13

벨로퍼트님의 리액트 네이티브를 다루는 기술 이라는 책을 보며
react native 스터디를 하던중에
async storage 를 다루는 예제가 나왔다

useEffect 와 함께 사용하여
첫 렌더링 시에는 async storage 에서 데이터를 get 해오고
첫 렌더링 + 데이터 변환 시에는 async storage 에 데이터를 set 하는 예제였는데
react native 의 async storage 는 비동기로 작동한다

const [data, setData] = useState('')

useEffect(() => {
	const asyncData = await AsyncStorage.getItem('data')
    setData(asyncData)
}, [])

useEffect(() => {
	AsyncStorage.setItem('data', data)
}, [data])

물론 간단한 예제여서 AsyncStorage 의 사용법에 집중하여 예제를 작성하신 것 같지만
useEffect 끼리의 순서가 보장되지는 않을 것 같다

useEffect 의 실행은 코드의 순서에 따라 실행되지만
내부의 비동기는 그렇지 않을 것이다

위 코드 같은 경우 getItem() 코드가 먼저 완료가 되지 않는다면
혹은 완료되더라도 setData() 가 setItem() 보다 먼저 완료되지 않는다면
setItem() 에 빈 데이터가 들어가게 될 것이고
만약 데이터 변경이 일어나지 않는다면
다음 렌더링 시에 빈 데이터만 get 해오게 될 것이다
데이터 손실 발생 위험이 있는 코드가 아닌가 싶다

아래의 useEffect 에 조건을 주어 첫 렌더링 시에는 setItem 을 하지 않거나 해야할 것 같다

function resolveAfter2Seconds() {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve('2000');
      }, 2000);
    });
  }

  function resolveAfter1Seconds() {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve('1000');
      }, 1000);
    });
  }

  async function asyncCall1() {
    const result = await resolveAfter1Seconds();
    console.log(result);
  }

  async function asyncCall2() {
    const result = await resolveAfter2Seconds();
    console.log(result);
  }

  useEffect(() => {
    asyncCall2()
  }, [])

  useEffect(() => {
    asyncCall1()
  }, [])

위처럼 useEffect 의 작성 순서가 완료 시점을 보장하지는 않는다
async 함수가 내부의 await 이 작성된 비동기 코드에 대해
비동기적으로 동작하긴 하지만
동기 방식으로 동작하는 것은 아니다

profile
떠돌이 생활을 하는. 실업자는 아니지만, 부랑 생활을 하는

0개의 댓글