[React Native][문제 해결] 앱에서의 비동기 문제를 해결해보자.

이지민·2024년 9월 2일
0

ReactNative

목록 보기
3/12

1.문제상황

function CreateBookScreen1({navigation}: {navigation: NavigationProp<ParamListBase>}) {
    const [genreInput, setGenreInput] = useState<Genre[]>([]);
    const [selectedGenre, setSelectedGenre] = useState<Genre | null>(null); // 선택된 장르 상태
    const { bookData, setBookData } = useCreateBook();
    const [errorMessege, setErrorMessege] = useState(false);

    const onNextButton = () => {
        if(errorMessege !== true && selectedGenre !== null){
            setBookData(prevData => ({
                ...prevData,
                genre: selectedGenre.genre_name // genre_id를 설정
            }));
        }
        
    };

    useEffect(() => {
        if (bookData.genre) { // bookData.genre가 업데이트되면
            console.log(bookData);
            navigation.navigate("CreateBook2", {
                genreId: selectedGenre?.genre_id // genre_id를 파라미터로 넘기기
            });
        }
    }, [bookData.genre, selectedGenre, navigation]);

우선 관련 코드이다...

이전 게시글을 보면, context api를 적용해서 책 생성에 필요한 bookData를 입력받아 관리하는 것을 알 수 있을 것이다.
근데 문제가 생겼다. 다음버튼을 누르면, 입력받은 데이터를 bookData에 업데이트하고, 화면이 넘어가도록 설정했었는데, bookData업데이트가 진행되지 않은채 화면이 넘어가버리는 것이다. 그래서 onNextButton에 bookData로그를 찍어봤을때 입력받은 genre가 null값이었다.

2.해결방법

function CreateBookScreen1({navigation}: {navigation: NavigationProp<ParamListBase>}) {
    const [genreInput, setGenreInput] = useState<Genre[]>([]);
    const [selectedGenre, setSelectedGenre] = useState<Genre | null>(null); // 선택된 장르 상태
    const { bookData, setBookData } = useCreateBook();
    const [errorMessege, setErrorMessege] = useState(false);

    const onNextButton = () => {
        if(errorMessege !== true && selectedGenre !== null){
            setBookData(prevData => ({
                ...prevData,
                genre: selectedGenre.genre_name // genre_id를 설정
            }));
        }
        
    };

    useEffect(() => {
        if (bookData.genre) { // bookData.genre가 업데이트되면
            console.log(bookData);
            navigation.navigate("CreateBook2", {
                genreId: selectedGenre?.genre_id // genre_id를 파라미터로 넘기기
            });
        }
    }, [bookData.genre, selectedGenre, navigation]);

사실 위의 코드가 해결한 방법이다.
react native는 javascript기반인데, 이 자바스크립트는 비동기로 데이터를 처리한다. 즉, 데이터가 처리되고 끝났는 걸 기다리지 않고 넘어간다는 것이다.

그래서 setBookData()뒤에 바로 navigation.navigate...를 붙이면, setBookData가 처리되는 도중에, 화면이 이동하는 것이다.

문제가 되는 건, 최종화면에서 문제가 되었었는데, 이 최종화면에서는 다음화면으로 넘어가는대신 완료버튼이 있어서 백엔드에 bookData를 body로 넘겨준다. 근데 이 비동기로 입력했던 bookData가 나중에 처리되면, bookData 일부가 빈채로 서버에 넘어가는 문제가 생기는 것이다. !

그래서, 다음버튼을 누르면, bookData의 genre가 set되고, useEffect로 이 bookData.genre를 변화를 감시하다가 set되서 genre가 바뀌면, 화면이 넘어가게 구현 했다!

3. 참고사항

useEffect의 상태 변화를 감지할 변수를 잘 지정해놓아야 한다. 예로들어 지역변수인, genreInput으로 해놓고 if문도 genreInput으로 해놓으면, genre를 바꾸는 즉시 화면이 넘어가 버리는 문제가 생길수 있다. ux 설계에 따라 그렇게 의도 할 수 도 있을꺼 같다. (예로 들면, 전화번호 입력하면 바로 다음 창으로 넘어간다던가)

profile
개발자가 되고싶어요

0개의 댓글