월 14,300원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결배달앱 클론코딩 [with React Native]
따라하다보니 index.d.ts 없는데 제가 놓친게 있는걸까요?
강의 보고 하고있는데 제가 놓친게 있는거같아요.. index.d.ts안보이는데 왜 그런건가요?지금 헤매고있습니다 ㅠㅠ
- 미해결배달앱 클론코딩 [with React Native]
npm i react-native-nmap --force 에러
이런 에러가 떠요 그리고 패키지.json에서 라이브러리 nmap을 지우면 다시 에러가 안뜨고 그래서 헤매고있습니다..
- 미해결배달앱 클론코딩 [with React Native]
navigation options presentation
안녕하세요.navigation options presentation 속성에 대한 질문입니다.만들고자 하는 서비스에서 탭간 이동시에도 화면 전환 효과를 주고싶은데, Stack.Screen 에서는 options에 presentation을 줄 수 있는데 Tab.Screen 에서는 options 에 presentation을 쳐도 자동완성이 안되는것 같아서 질문드립니다.1. 탭간 이동시에는 presentation 속성을 줄 수 있는 방법이 없나요?2. 만약 없다면 화면이 랜더링될때 직접 화면 전환 애니메이션 효과를 주는 방법으로 가는게 맞을까요?감사합니다 :)
- 미해결배달앱 클론코딩 [with React Native]
cocoapods 문제로 에러 발생
cocoapods 문제로 또 에러가 떴어요 ㅠ 에러 메세지는 아래와 같아요그거해서 cocoapods설치하고 npx ~ 로 Awesomeproject 생성했는데 아래 오류가 발생했어요터미널 껐다 켰는데도 같아요 ㅠ---------------------✔ Downloading template✔ Copying template✔ Processing template✔ Installing Ruby Gems✖ Installing CocoaPods dependencies (this may take a few minutes)error Framework build type is static library[Codegen] Generating ./build/generated/ios/React-Codegen.podspec.jsonAnalyzing dependenciesFetching podspec for DoubleConversion from ../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec[Codegen] Found FBReactNativeSpecFetching podspec for RCT-Folly from ../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec[Codegen] Found rncoreFetching podspec for boost from ../node_modules/react-native/third-party-podspecs/boost.podspecFetching podspec for glog from ../node_modules/react-native/third-party-podspecs/glog.podspecFetching podspec for hermes-engine from ../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec[Hermes] Using the release tarball from Maven CentralAdding spec repo trunk with CDN https://cdn.cocoapods.org/Downloading dependenciesInstalling CocoaAsyncSocket (7.6.5)Installing DoubleConversion (1.1.6)Installing FBLazyVector (0.72.4)Installing FBReactNativeSpec (0.72.4)Installing Flipper (0.182.0)Installing Flipper-Boost-iOSX (1.76.0.1.11)Installing Flipper-DoubleConversion (3.2.0.1)Installing Flipper-Fmt (7.1.7)Installing Flipper-Folly (2.6.10)Installing Flipper-Glog (0.5.0.5)Installing Flipper-PeerTalk (0.0.4)Installing FlipperKit (0.182.0)Installing OpenSSL-Universal (1.1.1100)Installing RCT-Folly (2021.07.22.00)Installing RCTRequired (0.72.4)Installing RCTTypeSafety (0.72.4)Installing React (0.72.4)Installing React-Codegen (0.72.4)Installing React-Core (0.72.4)Installing React-CoreModules (0.72.4)Installing React-NativeModulesApple (0.72.4)Installing React-RCTActionSheet (0.72.4)Installing React-RCTAnimation (0.72.4)Installing React-RCTAppDelegate (0.72.4)Installing React-RCTBlob (0.72.4)Installing React-RCTImage (0.72.4)Installing React-RCTLinking (0.72.4)Installing React-RCTNetwork (0.72.4)Installing React-RCTSettings (0.72.4)Installing React-RCTText (0.72.4)Installing React-RCTVibration (0.72.4)Installing React-callinvoker (0.72.4)Installing React-cxxreact (0.72.4)Installing React-debug (0.72.4)Installing React-hermes (0.72.4)Installing React-jsi (0.72.4)Installing React-jsiexecutor (0.72.4)Installing React-jsinspector (0.72.4)Installing React-logger (0.72.4)Installing React-perflogger (0.72.4)Installing React-rncore (0.72.4)Installing React-runtimeexecutor (0.72.4)Installing React-runtimescheduler (0.72.4)Installing React-utils (0.72.4)Installing ReactCommon (0.72.4)Installing SocketRocket (0.6.1)Installing Yoga (1.14.0)Installing YogaKit (1.18.1)Installing boost (1.76.0)Installing fmt (6.2.1)Installing glog (0.3.5)[!] /bin/bash -c set -e#!/bin/bash# Copyright (c) Meta Platforms, Inc. and affiliates.## This source code is licensed under the MIT license found in the# LICENSE file in the root directory of this source tree. set -e PLATFORM_NAME="${PLATFORM_NAME:-iphoneos}"CURRENT_ARCH="${CURRENT_ARCH}" if [ -z "$CURRENT_ARCH" ] || [ "$CURRENT_ARCH" == "undefined_arch" ]; then # Xcode 10 beta sets CURRENT_ARCH to "undefined_arch", this leads to incorrect linker arg. # it's better to rely on platform name as fallback because architecture differs between simulator and device if [[ "$PLATFORM_NAME" == "simulator" ]]; then CURRENT_ARCH="x86_64" else CURRENT_ARCH="arm64" fifi # @lint-ignore-every TXT2 Tab Literalif [ "$CURRENT_ARCH" == "arm64" ]; then cat <<\EOF >>fix_glog_0.3.5_apple_silicon.patchdiff --git a/config.sub b/config.subindex 1761d8b..43fa2e8 100755--- a/config.sub+++ b/config.sub@@ -1096,6 +1096,9 @@ case $basic_machine in basic_machine=z8k-unknown os=-sim ;;+ arm64-*)+ basic_machine=$(echo $basic_machine | sed 's/arm64/aarch64/')+ ;; none) basic_machine=none-none os=-noneEOF patch -p1 config.sub fix_glog_0.3.5_apple_silicon.patchfi export CC="$(xcrun -find -sdk $PLATFORM_NAME cc) -arch $CURRENT_ARCH -isysroot $(xcrun -sdk $PLATFORM_NAME --show-sdk-path)"export CXX="$CC" # Remove automake symlink if it existsif [ -h "test-driver" ]; then rm test-driverfi # Manually disable gflags include to fix issue https://github.com/facebook/react-native/issues/28446sed -i.bak -e 's/\@ac_cv_have_libgflags\@/0/' src/glog/logging.h.in && rm src/glog/logging.h.in.baksed -i.bak -e 's/HAVE_LIB_GFLAGS/HAVE_LIB_GFLAGS_DISABLED/' src/config.h.in && rm src/config.h.in.bak ./configure --host arm-apple-darwin cat << EOF >> src/config.h/* Add in so we have Apple Target Conditionals */#ifdef APPLE#include <TargetConditionals.h>#include <Availability.h>#endif /* Special configuration for ucontext */#undef HAVE_UCONTEXT_H#undef PC_FROM_UCONTEXT#if defined(__x86_64__)#define PC_FROM_UCONTEXT uc_mcontext->__ss.__rip#elif defined(__i386__)#define PC_FROM_UCONTEXT uc_mcontext->__ss.__eip#endifEOF # Prepare exported header includeEXPORTED_INCLUDE_DIR="exported/glog"mkdir -p exported/glogcp -f src/glog/log_severity.h "$EXPORTED_INCLUDE_DIR/"cp -f src/glog/logging.h "$EXPORTED_INCLUDE_DIR/"cp -f src/glog/raw_logging.h "$EXPORTED_INCLUDE_DIR/"cp -f src/glog/stl_logging.h "$EXPORTED_INCLUDE_DIR/"cp -f src/glog/vlog_is_on.h "$EXPORTED_INCLUDE_DIR/" patching file config.sub1 out of 1 hunks failed--saving rejects to config.sub.rej✖ Installing CocoaPods dependencies (this may take a few minutes)error Looks like your iOS environment is not properly set. Please go to https://reactnative.dev/docs/environment-setup?os=macos&platform=android and follow the React Native CLI QuickStart guide for macOS and iOS.info Run CLI with --verbose flag for more details.---------------------
- 미해결배달앱 클론코딩 [with React Native]
messaging().setBackgroundMessageHandler 핸들링 미적용
안녕하세요 강의 잘 듣고 있습니다. 현재 강의를 듣고 FCM을 구현하던 중 백그라운드 상태에서 push 알림을 핸들링 하고자하는데 어려움이 있어 질문 남겨요.messaging().setBackgroundMessageHandler(async remoteMessage => { const channelId = Platform.OS === 'ios' ? remoteMessage.category : remoteMessage.notification?.android?.channelId; console.log('FCM Channel ID:', channelId); if (channelId === 'example-sample') { // 해당 채널 ID가 'example-sample'인 경우 Push 알림 노출하지 않고 종료합니다. return; } }); 목표 ( 채널을 통한 알림 수신 거부 처리 )1. 앱서버에서 메시지 전송시 channel id값을 담아 발송.2. 앱이 background or quick 일때 특정 channel id시에는 push 알림 비 노출해당 메소드를 정상적으로 타긴 하지만 이미 디바이스에서는 알림이 오고 있습니다. 백그라운드 또는 종료 상태일경우 FCM 메시지를 컨트롤 할 수 없는 것일까요?
- 미해결배달앱 클론코딩 [with React Native]
Installing CocoaPods 설치가 안된다고 나옵니다
npx react-native@latest init AwesomeProject를 했는데 자동으로 다운이 되지 않고 sudo gem~으로 다운할려구 했는데 이것도 안되네요.. 왜이럴까요..!?
- 해결됨배달앱 클론코딩 [with React Native]
code push target 질문입니다
안녕하세요 제로초님. 저는 현재 프로젝트 중간에 투입된 경우인데, 이번에 새로 코드 푸시를 도입을 하기로 했습니다.강의를 보면서 차근차근 적용중에 있는데, 몇가지 질문을 드리고 싶습니다.질문이 네 가지 있습니다. target 질문제 프로젝트는 앱의 버전이 iOS 와 android 가 서로 상이합니다. 예로 들어 ios 의 버전은 4.0.0 대라면, android 는 2.0.0 대 입니다두 가지의 버전을 맞춰주는게 좋은가요? 다음 앱 배포시엔 둘다 5.0.0 으로 올려준다던지 하는 방법으로요. 다시 타겟 질문입니다만, minor 버전을 올릴 때 제가 이해한게 맞는지 확인차 질문드립니다. "3.2.9" -> "3.3.0" 버전으로 올라갈때 code push 의 버전이 "3.2" 타겟이기 때문에 "3.2" 타겟의 코드 푸시가 적용되지 않는다. 만약 이후에 "3.3.1" 버전으로 올리고 싶다면 code push target 을 "3.3" 으로 올리고 "codepush:build" 스크립트 명령어를 실행한다. 그러면 "3.3.0" 버전에 반영이 된다제가 이해한게 맞을까요? sentry와 함게 사용할때 의 질문.다른 분이 질문을 올린것을 봤습니다만, 저는 아직 잘 이해가 안되어 재질문드립니다 ㅠㅠSentry.init 에 들어가는 release 부분에서 패키지제이슨버전만 적어주신다고 하신건지 궁금합니다.release: "3.1.0" 처럼 간단하게 버전만 입력한다는 말씀이실까요?만약 맞다면 다시 1번 질문으로 돌아가서 Android, iOS 버전이 서로 다를땐release: ANDROID ? '2.0.1' : '3.0.1', 이런식으로 안드로이드 일땐, 2.0.1, iOS 일 땐 3.0.1 로 작업하면 되는걸까요? dist 값마찬가지로 sentry에 관련된 질문입니다. 제로초님은 dist 는 "dist값은 자기가 스스로 만드는 겁니다." 라고 답변을 달아주셨는데dist 는 제가 스스로 타겟처럼 규칙을 정해서 만들어주면 되는걸까요? 센트리 공식문서를 봐도 헷갈리네요 ㅠㅠ 질문은 이상입니다. 언제나 뭐든지 처음 세팅하는게 힘드네요. ㅠㅠ
- 미해결배달앱 클론코딩 [with React Native]
yarn android 시 메트로 서버가 자동으로 시작되지 않습니다.
$ yarn android yarn run v1.22.19 $ react-native run-android info Starting JS server... info Launching emulator... info Successfully launched emulator. info Installing the app... > Configure project :react-native-flipper WARNING:Software Components will not be created automatically for Maven publishing from Android Gradle Plugin 8.0. To opt-in to the future behavior, set the Gradle property android.disableAutomaticComponentCreation=true in the `gradle.properties` file or use the new publishing DSL. > Task :app:installDebug Installing APK 'app-debug.apk' on 'Nexus_5_API_30(AVD) - 11' for :app:debug Installed on 1 device. Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. See https://docs.gradle.org/8.0.1/userguide/command_line_interface.html#sec:command_line_warnings BUILD SUCCESSFUL in 7s 72 actionable tasks: 2 executed, 70 up-to-date info Connecting to the development server... 8081 info Starting the app on "emulator-5554"... Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.fooddelivery/.MainActivity } Done in 16.52s. 그냥 yarn android만 입력시에는 터미널이 따로 하나 띄워지는데 메트로 서버 없이 빈 터미널이 띄워집니다.RR로 리셋후yarn start로 매트로서버를 수동으로 실행시킨뒤에는 에뮬레이터 키고 연결이 잘 되는데 yarn android만 입력했을때는 메트로 서버가 자동으로 실행이 안되는데 해결 방법이 있을까요?윈도우 11java 11.0.20node 18.16.1사용중에 있습니다.
- 해결됨배달앱 클론코딩 [with React Native]
강의 외 추가학습 (카카오 소셜로그인)
우선 강의를 완강하고 추가학습으로 카카오 소셜로그인을 구현해보고 있습니다. (강의 너무 잘들었습니다!)https://github.com/crossplatformkorea/react-native-kakao-login위 라이브러리 사용해서 카카오 개발자 페이지의 설정도 모두 마치고 플랫폼 등록도 하여시뮬레이터로 시도하면 아래와 같은 오류가 발생합니다. Optional({ error = misconfigured; "error_code" = KOE009; "error_description" = "invalid android_key_hash or ios_bundle_id or web_site_url"; })찾아보니 전부 Xcode의 번들 ID와 카카오에 등록한 IOS 플랫폼 번들 ID가 달라서 그렇다고 하는데실기기에 연결하면 정상적으로 카카오에 로그인시도 성공되어 응답값도 받고 있습니다.구글링을 해도 도저히 해결이 안되서 이렇게 질문을 남기게 되었는데 혹시 제가 놓친 부분이 있을까요?번들 ID 문제인가 싶어서 다른걸로도 바꿔서 시도해봤는데 역시 시뮬레이터에서만 안됩니다ㅠ
- 미해결배달앱 클론코딩 [with React Native]
IOS 실기기 연결시 .env 환경변수
아이폰 실기기 연결하여 테스트 중인데, .env값 수정하였는데 계속 이전 값을 들고옵니다.(ex. API_URL에 설정해놓은 localhost값을 피씨 아이피로 변경 -> 재빌드해도 계속 이전 localhost를 들고옴)재빌드, 메트로 서버 종료, 앱삭제 등 여러가지 시도 하였는데 계속 이전 값을 유지하는데 보통 환경변수 파일 바꾸면 어떻게 하시는지 궁금합니다.이런 경우엔 빌드 폴더 클린 하는 방법말고 없을까여?
- 미해결배달앱 클론코딩 [with React Native]
TypeError: Cannot read property 'status' of undefined
안녕하세요 제로초님!회원가입을 하려면, 계속 아래와 같은 에러가 터미널에 뜹니다.error: [TypeError: Cannot read property 'status' of undefined] ERROR undefined어디가 잘 못 된걸까요,,.env파일 확인 해서 제 IP주소 확인했습니다.signUp 부분을 확인해야하는건지,,import React, {useCallback, useRef, useState, useEffect} from 'react'; import { ActivityIndicator, Alert, Platform, Pressable, StyleSheet, Text, TextInput, View, } from 'react-native'; import {NativeStackScreenProps} from '@react-navigation/native-stack'; import DismissKeyboardView from '../components/DismissKeyboardView'; import axios, {AxiosError} from 'axios'; import Config from 'react-native-config'; // 혹시 이거 설정법 아시나요 import {RootStackParamList} from '../../AppInner'; type SignUpScreenProps = NativeStackScreenProps<RootStackParamList, 'SignUp'>; function SignUp({navigation}: SignUpScreenProps) { const [loading, setLoading] = useState(false); const [email, setEmail] = useState(''); const [name, setName] = useState(''); const [password, setPassword] = useState(''); const emailRef = useRef<TextInput | null>(null); const nameRef = useRef<TextInput | null>(null); const passwordRef = useRef<TextInput | null>(null); useEffect(() => { console.log('email: ', email); console.log('name: ', name); console.log('password: ', password); }, [email, name, password]); const onChangeEmail = useCallback((text: string) => { setEmail(text.trim()); }, []); const onChangeName = useCallback((text: string) => { setName(text.trim()); }, []); const onChangePassword = useCallback((text: string) => { setPassword(text.trim()); }, []); const onSubmit = useCallback(async () => { if (loading) { return; } if (!email || !email.trim()) { return Alert.alert('알림', '이메일을 입력해주세요.'); } if (!name || !name.trim()) { return Alert.alert('알림', '이름을 입력해주세요.'); } if (!password || !password.trim()) { return Alert.alert('알림', '비밀번호를 입력해주세요.'); } if ( !/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/.test( email, ) ) { return Alert.alert('알림', '올바른 이메일 주소가 아닙니다.'); } if (!/^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[$@^!%*#?&]).{8,50}$/.test(password)) { return Alert.alert( '알림', '비밀번호는 영문,숫자,특수문자($@^!%*#?&)를 모두 포함하여 8자 이상 입력해야합니다.', ); } console.log(email, name, password); try { //:TODO log 삭제 console.log('LOGIN REQUEST'); console.log(Config.API_URL); setLoading(true); console.log(email); console.log(name); console.log(password); const response = await axios.post(`${Config.API_URL}/user`, { email, name, password, }); console.log('response: ', response.data); Alert.alert('알림', '회원가입 되었습니다.'); navigation.navigate('SignIn'); } catch (error) { console.log('error: ', error); const errorResponse = (error as AxiosError).response; console.error(errorResponse); if (errorResponse) { Alert.alert('알림'); } } finally { setLoading(false); } }, [loading, navigation, email, name, password]); const canGoNext = email && name && password; return ( <DismissKeyboardView> <View style={styles.inputWrapper}> <Text style={styles.label}>이메일</Text> <TextInput style={styles.textInput} onChangeText={onChangeEmail} placeholder="이메일을 입력해주세요" placeholderTextColor="#666" textContentType="emailAddress" value={email} returnKeyType="next" clearButtonMode="while-editing" ref={emailRef} onSubmitEditing={() => nameRef.current?.focus()} blurOnSubmit={false} /> </View> <View style={styles.inputWrapper}> <Text style={styles.label}>이름</Text> <TextInput style={styles.textInput} placeholder="이름을 입력해주세요." placeholderTextColor="#666" onChangeText={onChangeName} value={name} textContentType="name" returnKeyType="next" clearButtonMode="while-editing" ref={nameRef} onSubmitEditing={() => passwordRef.current?.focus()} blurOnSubmit={false} /> </View> <View style={styles.inputWrapper}> <Text style={styles.label}>비밀번호</Text> <TextInput style={styles.textInput} placeholder="비밀번호를 입력해주세요(영문,숫자,특수문자)" placeholderTextColor="#666" onChangeText={onChangePassword} value={password} keyboardType={Platform.OS === 'android' ? 'default' : 'ascii-capable'} textContentType="password" secureTextEntry returnKeyType="send" clearButtonMode="while-editing" ref={passwordRef} onSubmitEditing={onSubmit} /> </View> <View style={styles.buttonZone}> <Pressable style={ canGoNext ? StyleSheet.compose(styles.loginButton, styles.loginButtonActive) : styles.loginButton } disabled={!canGoNext || loading} onPress={onSubmit}> {loading ? ( <ActivityIndicator color="white" /> ) : ( <Text style={styles.loginButtonText}>회원가입</Text> )} </Pressable> </View> </DismissKeyboardView> ); } const styles = StyleSheet.create({ textInput: { padding: 5, borderBottomWidth: StyleSheet.hairlineWidth, }, inputWrapper: { padding: 20, }, label: { fontWeight: 'bold', fontSize: 16, marginBottom: 20, }, buttonZone: { alignItems: 'center', }, loginButton: { backgroundColor: 'gray', paddingHorizontal: 20, paddingVertical: 10, borderRadius: 5, marginBottom: 10, }, loginButtonActive: { backgroundColor: 'blue', }, loginButtonText: { color: 'white', fontSize: 16, }, }); export default SignUp; 아니면 AppInner부분인건지 모르겟습니다.import SignIn from './src/pages/SignIn'; import SignUp from './src/pages/SignUp'; import Orders from './src/pages/Orders'; import Delivery from './src/pages/Delivery'; import Settings from './src/pages/Settings'; import * as React from 'react'; import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; import {useSelector} from 'react-redux'; import {RootState} from './src/store/reducer'; import useSocket from './src/hooks/useSocket'; import {useEffect} from 'react'; import EncryptedStorage from 'react-native-encrypted-storage'; import axios, {AxiosError} from 'axios'; import {Alert} from 'react-native'; import userSlice from './src/slices/user'; import {useAppDispatch} from './src/store'; import Config from 'react-native-config'; import orderSlice from './src/slices/order'; export type LoggedInParamList = { Orders: undefined; Settings: undefined; Delivery: undefined; Complete: {orderId: string}; }; export type RootStackParamList = { SignIn: undefined; SignUp: undefined; }; const Tab = createBottomTabNavigator(); const Stack = createNativeStackNavigator<RootStackParamList>(); function AppInner() { const dispatch = useAppDispatch(); const isLoggedIn = useSelector((state: RootState) => !!state.user.email); console.log('isLoggedIn', isLoggedIn); const [socket, disconnect] = useSocket(); // 앱 실행 시 토큰 있으면 로그인하는 코드 useEffect(() => { const getTokenAndRefresh = async () => { try { const token = await EncryptedStorage.getItem('refreshToken'); if (!token) { return; } const response = await axios.post( `${Config.API_URL}/refreshToken`, {}, { headers: { authorization: `Bearer ${token}`, }, }, ); dispatch( userSlice.actions.setUser({ name: response.data.data.name, email: response.data.data.email, accessToken: response.data.data.accessToken, }), ); } catch (error) { console.error(error); if ((error as AxiosError as any).response?.data.code === 'expired') { Alert.alert('알림', '다시 로그인 해주세요.'); } } }; getTokenAndRefresh(); }, [dispatch]); useEffect(() => { const callback = (data: any) => { console.log(data); dispatch(orderSlice.actions.addOrder(data)); }; if (socket && isLoggedIn) { socket.emit('acceptOrder', 'hello'); socket.on('order', callback); } return () => { if (socket) { socket.off('order', callback); } }; }, [dispatch, isLoggedIn, socket]); useEffect(() => { if (!isLoggedIn) { console.log('!isLoggedIn', !isLoggedIn); disconnect(); } }, [isLoggedIn, disconnect]); useEffect(() => { axios.interceptors.response.use( response => { return response; }, async error => { const { config, response: {status}, } = error; if (status === 419) { if (error.response.data.code === 'expired') { const originalRequest = config; const refreshToken = await EncryptedStorage.getItem('refreshToken'); // token refresh 요청 const {data} = await axios.post( `${Config.API_URL}/refreshToken`, // token refresh api {}, {headers: {authorization: `Bearer ${refreshToken}`}}, ); // 새로운 토큰 저장 dispatch(userSlice.actions.setAccessToken(data.data.accessToken)); originalRequest.headers.authorization = `Bearer ${data.data.accessToken}`; // 419로 요청 실패했던 요청 새로운 토큰으로 재요청 return axios(originalRequest); } } return Promise.reject(error); }, ); }, [dispatch]); return isLoggedIn ? ( <Tab.Navigator> <Tab.Screen name="Orders" component={Orders} options={{title: '오더 목록'}} /> <Tab.Screen name="Delivery" component={Delivery} options={{title: '내 오더'}} /> <Tab.Screen name="Settings" component={Settings} options={{title: '내 정보'}} /> </Tab.Navigator> ) : ( <Stack.Navigator> <Stack.Screen name="SignIn" component={SignIn} options={{title: '로그인'}} /> <Stack.Screen name="SignUp" component={SignUp} options={{title: '회원가입'}} /> </Stack.Navigator> ); } export default AppInner;
- 미해결배달앱 클론코딩 [with React Native]
1. SafeAreaView 2. 상태관리
두가지 질문이 있습니다!NavigationContainer에 Safe view가 적용되있어최상단 App.tsx에는 작성안해도 되지만 내부에 중첩 라우터 컴포넌트의 경우 (Ing.tsx) 헤더가 없을 경우 적용되지 않던데이런 경우는 각 컴포넌트마다 SafeAreaView를 사용하는 수 밖에 없을까요? 강의에서는 상태관리를 리덕스 툴킷으로 하였는데 클라이언트 상태관리는 리덕스 툴킷, 서버 데이터 상태관리는 RTK나 리액트 쿼리등으로 따로 관리하시나요?
- 미해결배달앱 클론코딩 [with React Native]
키보드 관련 질문드립니다.
안녕하세요.안드로이드에서 react-native-keyboard-aware-scroll-view 라이브러리 사용해서 인스타그램 댓글창처럼 만들고있는데 FlatList로 댓글을 가져오고맨밑에 인풋창을 누르면 키보드가 상단으로 올라오면서 맨밑에 댓글이 가려지는 현상이있는데 이부분에 대해 해결방법이 있을까요?windowSoftInputMode는 adjustResize고 adjustPan모드로도 해봤는데 이건 맨위에 댓글 부분이 잘려나가더라구요.이것저것 해봤는데 안되서 여기다 질문 남깁니다.
- 미해결배달앱 클론코딩 [with React Native]
react-native-image-crop-picker --> openPicker 오류
안녕하세요ImagePicker.openCamera <- 정상 동작ImagePicker.openPicker <- Required permission missing위 내용입니다확인 부탁드립니다.
- 미해결배달앱 클론코딩 [with React Native]
앱 성능 측정은 어떻게 해야하나요?
React-Native로 개발한 앱을 리팩토링하려합니다.성능 비교를 위해서 리팩토링 이전에 측정해놓고 싶습니다.웹의 경우 라이트하우스로 성능을 측정했다면 모바일앱은 어떤걸로 측정 해야하나요?찾아보니까 Firebase Performance가 앱 성능 측정을 해주던데 표준이 되는 다른 측정 도구가 있나요? 아님 firebase를 활용해서 측정하면 될까요?
- 미해결배달앱 클론코딩 [with React Native]
Staging 테스트 질문이요!
안녕하세요 강의 잘 봤습니다.코드푸쉬를 적용하고 App Center까지 잘 올라온 걸 확인했습니다. 현재 앱을 TestFlight 앱으로 테스트 하고 있는데 Staging으로 코드푸쉬가 잘 적용되는지 확인하고 싶습니다. 혹시 Staging으로 올리고 변경된 codepush 내용을 TestFlight로 받는 방법이 있을까요?
- 해결됨배달앱 클론코딩 [with React Native]
[맥 전용] 애플 개발자 계정만들기 부분에서, identifiers 누락 부분 질문
[맥 전용] 애플 개발자 계정만들기 강의 파트에서 누락된 부분이 있어서, 이게 누락된건지 아니면 제가 빠뜨렸거나 다른 부분에서 있었던 내용인가 해서 질문올립니다~!certificates 부분 만들고, 6:42초 부분에 Profiles로 넘어가시는데, 6:53초부분에 AppID에 저는 fooddeliveryapp ID가 셀렉트 메뉴에 안뜨더라고요.그래서 검색해 보니 Identifiers 부분도 등록해야 프로파일 등록이 정상적으로 되는것 같던데, Identifiers 부분은 혹시 이 섹션 말고 다른 파트의 강의에서 나왔던 부분인가요? 현재는 이 부분은 강의에서 빠져 있네요Identifiers 등록 없이는 Profiles 등록이 안되는 것 같아 현재 구글의 다른 블로그 레퍼런스 검색해서 등록하려고 하는데,, 혹시 제가 다른 강의 파트서 나왔는데 누락했다면 그 강의 보고 다시 따라하려 합니다. 감사합니다
- 미해결배달앱 클론코딩 [with React Native]
React Native 소셜 로그인 관련 질문드립니다.
보통 RN에서 소셜 로그인을 하면 access token과 refresh token을 받아올 수 있는데, 이후 어떻게 해야할지 모르겠습니다..예를들어 kakao 로그인을 구현하여 토큰을 받는데 성공했는데, 이제 서버와 통신을 할 때 주로 어떤 방법으로 구현될까요?
- 미해결배달앱 클론코딩 [with React Native]
네이버맵 연동하기_build는 되는데 앱이 강제종료되는 현상
인프런 오류 때문에 코드블럭으로 에러가 올라가지 않아서 이미지로 대체합니다.모든 세팅을 마치고 npm run android로 빌드를 하면 앱이 바로 강제종료 됩니다.package.json "dependencies": { "@react-native-async-storage/async-storage": "^1.18.2", "@react-navigation/bottom-tabs": "^6.0.9", "@react-navigation/native": "^6.0.6", "@react-navigation/native-stack": "^6.2.5", "@reduxjs/toolkit": "^1.9.5", "axios": "^1.4.0", "react": "17.0.2", "react-native": "0.66.4", "react-native-config": "^1.5.1", "react-native-encrypted-storage": "^4.0.3", "react-native-keyboard-aware-scrollview": "^2.1.0", "react-native-nmap": "^0.0.66", "react-native-safe-area-context": "^3.3.2", "react-native-screens": "^3.10.1", "react-redux": "^8.1.1", "redux-flipper": "^2.0.2", "socket.io-client": "^4.7.0" }, "devDependencies": { "@babel/core": "^7.12.9", "@babel/runtime": "^7.12.5", "@react-native-community/eslint-config": "^2.0.0", "@types/jest": "^26.0.23", "@types/react-native": "^0.66.4", "@types/react-test-renderer": "^17.0.1", "@typescript-eslint/eslint-plugin": "^5.7.0", "@typescript-eslint/parser": "^5.7.0", "babel-jest": "^26.6.3", "eslint": "^7.14.0", "jest": "^26.6.3", "metro-react-native-babel-preset": "^0.66.2", "react-test-renderer": "17.0.2", "typescript": "^4.4.4" }, "resolutions": { "@types/react": "^17" },
- 해결됨배달앱 클론코딩 [with React Native]
remote push notification이 포그라운드에서 팝업되지 않아요
핸드폰 상단바에서 알림 표시만 되고 알림 팝업은 되지 않습니다.localNotification을 활용해서 팝업시켜 봤지만 그렇게 될 경우 onNotification과 함께 중복된 알람 2개가 동시에 옵니다.그리고 상단바를 열어서 localNotification으로 온 알람을 press하게 되면 데이터가 빈 오브젝트로 넘어와서 Screen Navigate를 하지 못합니다.(onNotification로 발생하는 알림에서만 데이터를 활용할 수 있는 상황입니다)결론은 onNotification로 온 알림이 팝업되어서 press를 하면 해당 화면을 이동시키는게 최종 목적이고현재 포그라운드에서 알림 팝업이 안되는 이슈를 해결하고 싶습니다..계속 찾아봐도 답을 못 찾겠어서 질문 남깁니다!// AndroidManifest.xml <meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground" android:value="true"/> <!-- Change the resource name to your App's accent color - or any other color you want --> <meta-data android:name="com.dieam.reactnativepushnotification.notification_color" android:resource="@color/white"/> <!-- or @android:color/{name} to use a standard color --> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" /> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" /> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.QUICKBOOT_POWERON" /> <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/> </intent-filter> </receiver> <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService" android:exported="false" > <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> // App.tsx PushNotification.configure({ onNotification: function (notification: any) { PushNotification.localNotification({ message: notification.message, title: notification.title, channelId: 'channel_general', }) } }) PushNotification.createChannel( { channelId: 'channel_general', channelName: '앱', }, (created: boolean) => console.log(`createChannel returned '${created}'`), );