묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결아바타 커뮤니티앱 만들기 (React Native Expo)
백엔드도 궁금합니다!
안녕하세요!클라이언트 부분 열심히 반복 수강 중에 있습니다 🙂 코드가 굉장히 깔끔하고 가독성이 좋아서 서버 부분도 배우고 싶더라구요! 서버 구성과 효율적인 코드를 작성하는 법도 배우고 싶다는 마음이 커지더라구요! 혹시 추후에 서버 강의를 진행하실 예정이 없으실까요? 없으시다면,,, 기존 강의에 있던 맛집 어플 서버 부분만 참고해도 충분할까요...?
-
미해결React Native with Expo: 제로초에게 제대로 배우기
ios에서 개발중이신 분들은
"ios": { "infoPlist": { "ITSAppUsesNonExemptEncryption": false, "NSLocationWhenInUseUsageDescription": "이 앱은 사용자의 위치를 기반으로 기능을 제공하기 위해 위치 정보가 필요합니다.(Allow $(PRODUCT_NAME) to use your location.)" } },app.json에서 요 부분 추가 하시고 npm run ios 로 빌드 다시 해보시면 될거에요.만약에 안되시면,rm -rf ios 명령어로 ios 파일 삭제 후 다시 빌드 해보시면 잘 될겁니다!
-
미해결React Native with Expo: 제로초에게 제대로 배우기
[질문아님] tabBarLabel 대신 tabBarShowLabel
궁금해서 Gemini에게 물어봤는데요..!tabBarLabel이 {null}로 반환하는 것과 {""} 빈문자열 넣는 법.이 두가지 차이점을 물어보다가 아래 tabBarShowLabel 속성이 있다는 걸 알게됐고,요 속성은 아예 레이아웃 처리가 되지 않는 다는 걸 알게됐습니다.부모 <Tabs />에 한번만 쓰면 하위에 다 적용되는 구조입니다.tabBarShowLabel: false,일단 저는 이 속성 사용해보고있는데,좋은 것 같아용 ㅎㅎ제로초님은 이걸 사용하지 않으시던데,혹시나 요거 사용하면 안되는거면 댓글 달아주세용ㅎㅎ
-
미해결아바타 커뮤니티앱 만들기 (React Native Expo)
댓글 버튼 하단에 고정되지 않는 이슈
node 버전 : v24.11.1[id.tsx] 파일입니다. 현재 상세 페이지를 가면 아래와 같이 댓글 버튼이 상단으로 올라오는 현상이 생겼습니다. 또한 답글 남기기를 눌러도 focus는 댓글 input으로 되지만, 화면처럼 스크롤이 내려가는 현상은 안나타납니다. npx expo start를 이용하여, 실기기로 테스트한겁니다!import AuthRoute from "@/components/AuthRoute"; import CommentItem from "@/components/CommentItem"; import FeedItem from "@/components/FeedItem"; import InputField from "@/components/InputField"; import { colors } from "@/constants"; import useCreateComment from "@/hooks/queries/useCreateComment"; import useGetPost from "@/hooks/queries/useGetPost"; import useKeyboard from "@/hooks/useKeyboard"; import { useLocalSearchParams } from "expo-router"; import { Fragment, useRef, useState } from "react"; import { Keyboard, KeyboardAvoidingView, Platform, Pressable, ScrollView, StyleSheet, Text, TextInput, View, } from "react-native"; import { SafeAreaView, useSafeAreaInsets, } from "react-native-safe-area-context"; export default function PostDetailScreen() { const { id } = useLocalSearchParams(); const { data: post, isPending, isError } = useGetPost(Number(id)); const createComment = useCreateComment(); const [content, setContent] = useState(""); const scrollRef = useRef<ScrollView | null>(null); const inputRef = useRef<TextInput | null>(null); const [parentCommentId, setParentCommentId] = useState<number | null>(null); const { isKeyboardVisible } = useKeyboard(); const insets = useSafeAreaInsets(); if (isPending || isError) { return <></>; } const handleReply = (commentId: number) => { setParentCommentId(commentId); inputRef.current?.focus(); }; const handleCancelReply = () => { setParentCommentId(null); Keyboard.dismiss(); }; const handleSubmitComment = () => { const commentData = { postId: post.id, content: content, }; if (parentCommentId) { createComment.mutate({ ...commentData, parentCommentId }); setContent(""); handleCancelReply(); return; } if (parentCommentId) { createComment.mutate({ ...commentData, parentCommentId }); setContent(""); handleCancelReply(); return; } createComment.mutate(commentData); setContent(""); setTimeout(() => { scrollRef.current?.scrollToEnd(); }, 500); }; return ( <AuthRoute> <SafeAreaView style={styles.container} edges={["right", "left", "bottom"]} > <KeyboardAvoidingView contentContainerStyle={styles.awareScrollViewContainer} behavior="height" keyboardVerticalOffset={ Platform.OS === "ios" || isKeyboardVisible ? 100 : insets.bottom } > <ScrollView ref={scrollRef} style={{ marginBottom: 75 }} contentContainerStyle={styles.scrollViewContainer} > <View style={{ marginTop: 12 }}> <FeedItem post={post} isDetail /> <Text style={styles.commentCount}> 댓글 {post.commentCount}개 </Text> </View> {post.comments?.map((comment) => ( <Fragment key={comment.id}> <CommentItem parentCommentId={parentCommentId} onReply={() => handleReply(comment.id)} onCancelReply={handleCancelReply} comment={comment} /> {comment.replies.map((reply) => ( <CommentItem key={reply.id} comment={reply} isReply /> ))} </Fragment> ))} </ScrollView> <View style={styles.commentInputContainer}> <InputField ref={inputRef} value={content} returnKeyType="send" onSubmitEditing={handleSubmitComment} onChangeText={(text) => setContent(text)} placeholder={ parentCommentId ? "답글 남기는중..." : "댓글을 남겨보세요." } rightChild={ <Pressable disabled={!content} style={styles.inputButtonContainer} onPress={handleSubmitComment} > <Text style={styles.inputButtonText}>등록</Text> </Pressable> } /> </View> </KeyboardAvoidingView> </SafeAreaView> </AuthRoute> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: colors.WHITE, }, awareScrollViewContainer: { flex: 1, backgroundColor: colors.GRAY_200, }, scrollViewContainer: { backgroundColor: colors.GRAY_200, }, commentCount: { marginTop: 12, backgroundColor: colors.WHITE, paddingVertical: 12, paddingHorizontal: 16, fontSize: 16, fontWeight: "bold", }, commentInputContainer: { width: "100%", borderTopColor: colors.GRAY_200, borderTopWidth: StyleSheet.hairlineWidth, backgroundColor: colors.WHITE, padding: 16, bottom: 0, position: "absolute", }, inputButtonContainer: { backgroundColor: colors.ORANGE_600, padding: 8, borderRadius: 5, }, inputButtonText: { color: colors.WHITE, fontWeight: "bold", }, });
-
해결됨아바타 커뮤니티앱 만들기 (React Native Expo)
SafeAreaView 적용 기준 문의
아바타 만들기 /post 에는 글쓰기, 수정, 상세화면에 대한 정의가 되어 있습니다./post/[id].tsx/post/write.tsx/post/update/[id].tsx 글쓰기와 수정은 SafeAreaView를 적용하지 않았는데 상세보기에서 적용한 이유와 어떤 기준에 의해 적용하였는지 문의 드립니다./post/_layout.tsx 내에 Stack.Screen에서 headerShown : false일때 SafeAreaView를 적용하는걸로 생각했는데 그렇지 않은것 같습니다. 감사합니다.
-
해결됨아바타 커뮤니티앱 만들기 (React Native Expo)
스크린 옵션 아이콘
피그마 디자인에서는 < 를 사용했는데강의에서는 Foundation "home"을 사용했어요!의도하신걸까요? 디자인이 최종 시안이라던가.. 그게 아니라면강의는 동영상이니 바꾸는데 공수가 많이 들어가니피그마에서 아이콘 바꿔주셔도 좋을것같습니다! 잡담으로 저는 자바스프링 백엔드로 시작해서 jQuery/Angular/Vue/React/Next를 풀스택으로 쓰는 회사들로 이직하면서 최종적으로 코틀린스프링을 메인스택으로 하고 있는데요.취미/공부/사이드 프로젝트로 Next.js랑 Flutter 배우고 이번에 RN배우는데 강사님의 코드퀄리티나 강의력이 깔끔한것 같아서 잘 보고 있습니다ㅎㅎ 25년 초에 릴리즈한 강의인데 26년에도 미션이나 질문에도 답 잘 달아주셔서 감사합니다.
-
미해결아바타 커뮤니티앱 만들기 (React Native Expo)
[Note] 안드로이드 네비게이션 헤더 이슈 안내
❗질문 작성시 꼭 참고해주세요에러 메세지에서 단서를 찾을 수 있는 경우가 많습니다. 에러 메세지를 읽고 한번 검색해보시는것을 추천드립니다.질문글을 작성하실때는, 현재 문제(또는 에러)와 코드나 github을 첨부해주세요.개발중인 OS, ReactNative, Node 버전 등의 개발환경을 알려주셔야합니다.에러메세지는 일부분이 아닌 전체 상황을 올려주세요. 일부만 보여주시면 답변이 어렵습니다.에러 잘라서 올리시면 안됩니다!(에러 일부만 자르거나 일부만 복사하지말아주세요) 지금은 잘 되는 것 같은데(제가 아직 안드로이드 애뮬레이터로만 테스트 한 상태이긴 하지만)혹시 지금도 안되는지 궁금합니다!
-
미해결아바타 커뮤니티앱 만들기 (React Native Expo)
ActionSheet
ellipsis-vertical 클릭시강의와 같이 실제 아이폰 actionsheet 처럼 보이지 않고 다른 style이 입혀진듯하게 보이고있습니다.에러코드는 없습니다. 노드 : 20.19.6시뮬레이터 : iOS 26.2ReactNative : 0.81.5 작업중인 시뮬레이터 화면 강의 시뮬레이터 화면 import { colors } from "@/constants"; import useAuth from "@/hooks/queries/useAuth"; import type { Post } from "@/types"; import { useActionSheet } from "@expo/react-native-action-sheet"; import { Ionicons, MaterialCommunityIcons, Octicons } from "@expo/vector-icons"; import React from "react"; import { Pressable, StyleSheet, Text, View } from "react-native"; import Profile from "./Profile"; interface FeedItemProps { post: Post; } function FeedItem({ post }: FeedItemProps) { const { auth } = useAuth(); const likeUsers = post.likes?.map((like) => Number(like.userId)); const isLiked = likeUsers?.includes(Number(auth.id)); const { showActionSheetWithOptions } = useActionSheet(); const handlePressOption = () => { const options = ["삭제", "수정", "취소"]; showActionSheetWithOptions({ options }, (selectedIndex?: number) => { console.log("selectedIndex", selectedIndex); switch (selectedIndex) { case 0: //삭제 break; case 1: //수정 break; case 2: break; default: break; } }); }; return ( <View style={styles.container}> <View style={styles.contentContainer}> <Profile imageUri={post.author.imageUri} nickname={post.author.nickname} createdAt={post.createdAt} onPress={() => {}} option={ auth.id === post.author.id && ( <Ionicons name="ellipsis-vertical" size={24} color={colors.BLACK} onPress={handlePressOption} /> ) } /> <Text style={styles.title}>{post.title}</Text> {/* numberOfLines 게시글 내용 3줄까지만 보이게 */} <Text numberOfLines={3} style={styles.description}> {post.description} </Text> </View> <View style={styles.menuContainer}> <Pressable style={styles.menu}> <Octicons name={isLiked ? "heart-fill" : "heart"} size={16} color={isLiked ? colors.ORANGE_600 : colors.BLACK} /> <Text style={isLiked ? styles.activeMenuText : styles.menuText}> {post.likes.length || "좋아요"} </Text> </Pressable> <Pressable style={styles.menu}> <MaterialCommunityIcons name="comment-processing-outline" size={16} color={colors.BLACK} /> <Text style={styles.menuText}>{post.commentCount || "댓글"}</Text> </Pressable> <Pressable style={styles.menu}> <Ionicons name="eye-outline" size={16} color={colors.BLACK} /> <Text style={styles.menuText}>{post.viewCount}</Text> </Pressable> </View> </View> ); } const styles = StyleSheet.create({ container: { backgroundColor: colors.WHITE, }, contentContainer: { padding: 16, }, menuContainer: { flexDirection: "row", alignItems: "center", justifyContent: "space-around", borderTopColor: colors.GRAY_300, borderTopWidth: StyleSheet.hairlineWidth, }, title: { fontSize: 18, color: colors.BLACK, fontWeight: "600", marginVertical: 8, }, description: { fontSize: 16, color: colors.BLACK, marginBottom: 14, }, menu: { flexDirection: "row", alignItems: "center", justifyContent: "center", paddingVertical: 16, width: "33%", gap: 4, }, menuText: { fontSize: 14, color: colors.GRAY_700, }, activeMenuText: { fontWeight: "500", color: colors.ORANGE_600, }, }); export default FeedItem; import queryClient from "@/api/queryClient"; import useAuth from "@/hooks/queries/useAuth"; import { ActionSheetProvider } from "@expo/react-native-action-sheet"; import { QueryClientProvider } from "@tanstack/react-query"; import { Stack } from "expo-router"; import { useEffect } from "react"; import "react-native-reanimated"; import Toast from "react-native-toast-message"; export const unstable_settings = { anchor: "(tabs)", }; export default function RootLayout() { return ( <ActionSheetProvider> <QueryClientProvider client={queryClient}> <RootNavigator /> <Toast /> </QueryClientProvider> </ActionSheetProvider> ); } function RootNavigator() { const { auth } = useAuth(); useEffect(() => { auth.id && Toast.show({ type: "success", text1: `${auth.nickname ?? "회원"}님 환영합니다!`, }); }, [auth.id]); return ( <Stack> <Stack.Screen name="(tabs)" options={{ headerShown: false }} /> <Stack.Screen name="auth" options={{ headerShown: false }} /> <Stack.Screen name="post" options={{ headerShown: false }} /> <Stack.Screen name="modal" options={{ presentation: "modal", title: "Modal" }} /> </Stack> ); }
-
미해결React Native with Expo: 제로초에게 제대로 배우기
Location.getCurrentPositionAsync({}); 에러
npm ls react 19.1.0npm ls react-native 0.81.5npm ls expo 54.0.27버전을 알려주시면 질문자분과 동일한 환경에서 답변 드릴 수 있습니다.에뮬레이터에 location도 설정했는데 왜 마크표시를 누르면 아래 에러가 발생하는걸까요.. 빌드 지우고 다시 설치하고도 해봤습니다. LOG getMyLocation granted ERROR [Error: Uncaught (in promise, id: 1) Error: Current location is unavailable. Make sure that location services are enabled] Code: construct.js 2 | var setPrototypeOf = require("./setPrototypeOf.js"); 3 | function _construct(t, e, r) { > 4 | if (isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); | ^ 5 | var o = [null]; 6 | o.push.apply(o, e); 7 | var p = new (t.bind.apply(t, o))(); Call Stack construct (<native>) apply (<native>) _construct (node_modules/@babel/runtime/helpers/construct.js:4:65) Wrapper (node_modules/@babel/runtime/helpers/wrapNativeSuper.js:15:23) construct (<native>) _callSuper (node_modules/@babel/runtime/helpers/callSuper.js:5:108) constructor (node_modules/expo-modules-core/src/errors/CodedError.ts:11:5)
-
미해결React Native with Expo: 제로초에게 제대로 배우기
.
.
-
미해결React Native with Expo: 제로초에게 제대로 배우기
EAS preview 빌드 후 Device에서 카카오 로그인 브라우저가 안켜짐
저는 강의 수강 후 개인 앱을 만들고 있습니다.EAS preview 빌드 후 해당 빌드 내용을 Orbit을 통해 에뮬레이터에서는 로그인 부라우저가 뜨고 다음 화면까지 이동하는 프로세스가 잘 동작하는 것 까지 확인했습니다. 그런데 제 실제 디바이스에서 구동해보면 카카오 로그인 버튼을 누르면 설정해놓은 Loading spining만 뜨다가 화면이 넘어가지질 않습니다.로그도 못보고 있어서 해결을 못하고 있는데 혹시 이런 경우 관련 해결팁이 있을까요 ?저는 이 화면으로 넘어가고 싶은데 안되네요 ㅠㅠ..
-
미해결React Native with Expo: 제로초에게 제대로 배우기
폴더 구조 관련 질문
제로초님 안녕하세요 expo 프로젝트의 폴더 구조에 대해서 고민이 있습니다.!!현재 src/app 폴더에서 페이지들을 관리하고 있고각 페이지 내부에서만 사용하는 하위 컴포넌트들은 src/app/settings/_components/AccountSettingsSection.tsx와 같이 _components 폴더 하위에 배치하고, named export를 통해 라우트로 잡히지 않게 하고 있습니다. 문제는 없지만 프로젝트를 실행시키면 WARN Route "./settings/_components/AccountSettingsSection/AccountSettingsSection.tsx" is missing the required default export. Ensure a React component is exported as default.라는 경고 메시지가 app/ 내부에서 named export 한 모든 하위 컴포넌트를 대상으로 출력됩니다. Next.js처럼 _components 내부의 하위 컴포넌트들은 완전히 무시하도록 하고 싶은데 아무리 찾아봐도 무시할 방법이 없는 거 같습니다 ㅠ 제로초님께서는 어떤 방법으로 페이지 내부 하위 컴포넌트들을 배치하시는지 궁금합니다..!! 관리하기 용이한 폴더 구조가 있다면 추천해주실 수 있으신가요??
-
미해결아바타 커뮤니티앱 만들기 (React Native Expo)
안드로이드 폰과 PC에서 테스트할때 화면 안보임과 오류 문의
일단 위 화면까지는 PC에서 나오는데, Development servers에 링크를 클릭하면 아무 반응이 없는데, 어떻게 해야하는지 문의드립니다.그리고, 실제 안드로이드 폰에서 테스트시에도, 아래와 같이 홈화면에 아무것도 나오지 않고, 하단 메뉴만 노출되고, 내 프로필을 클릭하면 하단 이미지 두번째처럼 오류가 나고 있습니다. 어떻게 해결해야하는지 문의드립니다.
-
미해결React Native with Expo: 제로초에게 제대로 배우기
혹시 리액트네이티브 관련해서 좋은 참고서도 있을까요??
강의 내용과는 별개로, 개인적으로 공부를 더 하고 싶은 부분이 있어 도움을 요청드립니다.현재 출퇴근 시간에 활용할 목적으로 실습보다는 내용이나 이론이 탄탄한 개발 서적을 찾고 있습니다. 예를 들면, JS Deep Dive처럼 언어의 원리나 깊은 내용을 다루는 책을 선호합니다.강의 영상이나 소리 대신 책으로 글을 읽으며 내용을 훑어보고, "이런 기능도 있구나, 이럴 땐 이렇게 하는구나" 하며 지식을 확장하는 용도로 활용하고 싶습니다.혹시 추천해주실 만한 서적이 있을까요?
-
미해결React Native with Expo: 제로초에게 제대로 배우기
제로초님께서는 Nativewind는 사용안하지는지 궁금합니다.
React/Next.js 프로젝트에서 Tailwind를 많이 사용하는 추세인데, 이와 매우 유사한 React Native 의 Natviewind 라는게 있더군요. Nativewind를 사용하면 기존 Tailwind에서 처럼 className으로 빠르게 스타일링할 수 있고 웹과 모바일 간 일관된 스타일 코드를 유지할 수 있는 장점이 있는 것 같습니다. React Native 기초 강의이므로 기본 React Native CSS 사용을 통해 구현하는 방식을 보여주신 것인지 궁금합니다.
-
미해결아바타 커뮤니티앱 만들기 (React Native Expo)
iOS 빌드 후 실기기에서 앱 시작
강사님 해결 되었습니다! 글 삭제가 안보이네요..
-
미해결React Native with Expo: 제로초에게 제대로 배우기
.
.
-
미해결아바타 커뮤니티앱 만들기 (React Native Expo)
[5-2] 글 목록 무한스크롤 구현하기 with InfiniteQuery 10:40/ useScrollTop(ref) 사용관련
18번째 줄에서 useEffect 같은 훅에서 호출한 게 아닌데 useScrollToTop()은 어떻게 트리거되어 동작하는지 궁금합니다. 6번째 줄에서 useScrollToTop() 훅은 "@react-navigation/native"에서 가져오고 있는데, "expo-router"와 같이 사용해도 되나요?
-
미해결React Native with Expo: 제로초에게 제대로 배우기
eas build:configure 안되는데, "git"이 반드시 설치되어 있어야 하나요?
eas build:configure 안되는데, "git"이 반드시 설치되어 있어야 하나요?
-
미해결React Native with Expo: 제로초에게 제대로 배우기
.
.