inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

아바타 커뮤니티앱 만들기 (React Native Expo)

[5-4] 글 수정/삭제 기능 구현하기(2) - API 연동

[5-4]글 수정/삭제 기능 구현하기(2) - API연동 부분에서 수정하기 누르면 제목과 내용이 비어있는데요,,, 한번 더 수정하기 눌러야 이전 제목과, 내용이 나옵니다...

284

ksw

작성한 질문수 16

0

image.pngimage.png

import CustomButton from "@/components/CustomButton";
import DescriptionInput from "@/components/DescriptionInput";
import TitleInput from "@/components/TitleInput";
import { ImageUri } from "@/types";
import { router, useLocalSearchParams, useNavigation } from "expo-router";
import { useEffect } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { StyleSheet,View } from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import useGetPost from "@/hooks/queries/useGetPost";
import useUpdatePost from "@/hooks/queries/useUpdatePost";

type FormValues= {
    title:string;
    description: string;
    imageUris:ImageUri[];
};

export default function PostUpdateScreen () {
    const {id} = useLocalSearchParams(); 
    const navigation = useNavigation();
    const {data:post} = useGetPost(Number(id));
    const updatePost = useUpdatePost();
    
    const postForm = useForm<FormValues>({
        defaultValues:{
            title:post?.title,
            description:post?.description,
            imageUris:post?.imageUris,
        },
    });


    const onSubmit = (formValues: FormValues)=> {
        updatePost.mutate({
            id: Number(id),
            body: formValues,
        },{
            onSuccess:() => router.back(),
        }
    );
    };
    useEffect(()=>{
        navigation.setOptions({
            headerRight:() => (
                <CustomButton 
                label="저장" 
                size="medium" 
                variant="standard" 
                onPress={postForm.handleSubmit(onSubmit)}
                />  
            ),
        }); 
    },[]);
    return(
        <FormProvider {...postForm}>
        <KeyboardAwareScrollView contentContainerStyle={styles.container}>
            <TitleInput />
            <DescriptionInput />
        </KeyboardAwareScrollView>
        </FormProvider>
    );
}
const styles = StyleSheet.create({
    container:{
        margin:16,
        gap:16,

    },  
});

javascript react react-native typescript react-query

답변 3

0

ᆞkaraku

저도 이 문제 때문에 어떤식으로 처리해야할지 몰랐는데 처리했습니다 감사합니다

 

const postForm = useForm<FormValues>({
        // defaultValues: {
        //     title: post?.title,
        //     description: post?.description,
        //     imageUris: post?.imageUris,
        // },
    });
    // useEffect를 사용해서 서버에서 받아온 게시글(post) 정보를 postForm이라는 폼(form)에 채워 넣는 코드
    useEffect(() => {
        if (post) {
            postForm.reset({
                title: post?.title,
                description: post?.description,
                imageUris: post?.imageUris,
            })
        }
    }, [post, postForm])

0

Kyo

글을 등록하고, 글 목록에서 바로 수정을 누를 경우 비어있다는 말씀이시죠?

PostUpdateScreen에서 defaultValues는 지우고, post가 변경될때 값을 넣어주도록 코드를 추가해보시겠어요?

 

const postForm = useForm<FormValues>();
//...

 useEffect(() => {
    if (post) {
      postForm.reset({
        title: post.title,
        description: post.description,
        isVoteAttached: post.hasVote,
        imageUris: post.imageUris,
      });
    }
  }, [post, postForm]);

 

0

ksw

선생님 말씀은,, 하기 부분을 수정하라는 말씀이시지요??

 

import CustomButton from "@/components/CustomButton";
import DescriptionInput from "@/components/DescriptionInput";
import TitleInput from "@/components/TitleInput";
import { ImageUri } from "@/types";
import { router, useLocalSearchParams, useNavigation } from "expo-router";
import { useEffect } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { StyleSheet,View } from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import useGetPost from "@/hooks/queries/useGetPost";
import useUpdatePost from "@/hooks/queries/useUpdatePost";

type FormValues= {
    title:string;
    description: string;
    imageUris:ImageUri[];
};

export default function PostUpdateScreen () {
    const {id} = useLocalSearchParams(); 
    const navigation = useNavigation();
    const {data:post} = useGetPost(Number(id));
    const updatePost = useUpdatePost();
    
    const postForm = useForm<FormValues>({
        defaultValues:{
            title:post?.title,
            description:post?.description,
            imageUris:post?.imageUris,
        },
    });


    const onSubmit = (formValues: FormValues)=> {
        updatePost.mutate({
            id: Number(id),
            body: formValues,
        },{
            onSuccess:() => router.back(),
        }
    );
    };
    useEffect(()=>{
        navigation.setOptions({
            headerRight:() => (
                <CustomButton 
                label="저장" 
                size="medium" 
                variant="standard" 
                onPress={postForm.handleSubmit(onSubmit)}
                />  
            ),
        }); 
    },[]);
    return(
        <FormProvider {...postForm}>
        <KeyboardAwareScrollView contentContainerStyle={styles.container}>
            <TitleInput />
            <DescriptionInput />
        </KeyboardAwareScrollView>
        </FormProvider>
    );
}
const styles = StyleSheet.create({
    container:{
        margin:16,
        gap:16,

    },  
});

 

상기 코드부분 중,,,아래 부분을 삭제하고

const postForm = useForm<FormValues>({
        defaultValues:{
            title:post?.title,
            description:post?.description,
            imageUris:post?.imageUris,
        },
    });

 

아래 내용을 추가하란 말씀이시지요???

const postForm = useForm<FormValues>(); //... useEffect(() => { if (post) { postForm.reset({ title: post.title, description: post.description, isVoteAttached: post.hasVote, imageUris: post.imageUris, }); } }, [post, postForm]);

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다. ksw님.

게시글 수정 시 제목과 내용이 초기 화면에 빈상태로 나타나는 문제는 데이터가 비동기로 로드되는 과정에서 발생할 수 있는 일반적인 이슈입니다. 이 문제를 해결하기 위한 몇 가지 접근 방법을 제시드리겠습니다.

주요 원인

  1. 비동기 데이터 로드: useGetPost 훅에서 데이터를 불러오는 로직이 완료되기 전에 컴포넌트가 렌더링되어, defaultValues에 초기 값이 전달되지 않는 경우가 있습니다.
  2. 상태 초기화: defaultValues는 훅이 처음 호출될 때만 설정되며, 이후 post가 업데이트되더라도 재설정되지 않습니다.

해결 방법

  1. useEffect를 사용한 상태 업데이트
    • useEffect를 활용하여 데이터 로딩 이후에 postForm.reset을 호출하여 폼의 상태를 갱신하는 방법입니다. 이를 통해 post가 로드된 후 데이터를 동기화할 수 있습니다.
   useEffect(() => {
       if (post) {
           postForm.reset({
               title: post.title,
               description: post.description,
               imageUris: post.imageUris,
           });
       }
   }, [post, postForm]);
  1. 로딩 상태 관리
    • 데이터 로딩이 완료되기 전까지 로딩 상태를 표시하고, 로딩이 완료된 후에만 사용자가 수정을 할 수 있도록 하는 방법도 고려해볼 수 있습니다. 이를 통해 UX 개선이 가능합니다.

참고할 만한 링크

  • staleTime과 invalidateQueries: React Query를 활용한 데이터 갱신과 조건부 무효화 관련 정보를 얻을 수 있습니다. 이와 비슷한 데이터 상태 관리 이슈에 대한 해답을 찾는 데 도움이 될 것입니다.

문제가 해결되기를 바라며, 추가적인 질문이 있다면 언제든지 문의해 주세요.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해 드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

secureTextEntry 설정에 관해

0

58

2

expo 55 tabs 사라짐 이슈

0

83

2

백엔드도 궁금합니다!

1

86

1

댓글 버튼 하단에 고정되지 않는 이슈

0

53

1

SafeAreaView 적용 기준 문의

0

82

2

스크린 옵션 아이콘

0

56

2

[Note] 안드로이드 네비게이션 헤더 이슈 안내

0

67

2

ActionSheet

0

87

1

안드로이드 폰과 PC에서 테스트할때 화면 안보임과 오류 문의

0

99

1

iOS 빌드 후 실기기에서 앱 시작

1

71

1

[5-2] 글 목록 무한스크롤 구현하기 with InfiniteQuery 10:40/ useScrollTop(ref) 사용관련

0

84

2

클라이언트 사이드에서 세션 관련 질문

0

82

2

Android 에뮬레이터 환경설정 및 실행 (for Mac) 에러 문의

0

113

1

[5-13] useLikePost 쿼리 구현 중 Tanstack Query 관련 질문

0

63

1

Expo 54 버전 ios에서 headerLeft

1

140

2

어플 개발 후 배포 시에 주의할 사항이 있을까요?

0

79

1

코드 수정 시 ios 시뮬레이터에서 자동반영이 안 되는데 왜그럴까요?

0

92

1

텍스트가 다 상단위로 올라가있는데 어떻게 해야할까요?

0

78

2

Axios Network error...

0

151

2

강의는 52버전인데 expo가 현재 54버전이에요

0

310

1

[TIP] SafeAreaView 사용할 때마다 자꾸 ios에서 위아래가 빵꾸 나시는 분들 필독

0

238

2

키보드 이슈 관련 해결 질문

0

74

1

android header를 ios처럼 바꾸기

0

70

1

CustomButton 코드 버튼 관련 질문

0

66

1