강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

ksw님의 프로필 이미지
ksw

작성한 질문수

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

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

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

작성

·

206

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,

    },  
});

답변 3

0

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

 

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님의 프로필 이미지
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]);

 

ksw님의 프로필 이미지
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 인턴입니다. 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를 활용한 데이터 갱신과 조건부 무효화 관련 정보를 얻을 수 있습니다. 이와 비슷한 데이터 상태 관리 이슈에 대한 해답을 찾는 데 도움이 될 것입니다.

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

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

ksw님의 프로필 이미지
ksw

작성한 질문수

질문하기