벨로퍼트님의 리액트 네이티브를 다루는 기술 이라는 책을 보며
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 이 작성된 비동기 코드에 대해
비동기적으로 동작하긴 하지만
동기 방식으로 동작하는 것은 아니다