묻고 답해요
137만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
getProfileQuery.data 반환값들의 타입을 인식하지 못하는 것 같아요! 도와주시면 감사하겠습니다
강사님은 const {} = getProfileQuery.data || {};에서왼쪽 {} 안에 email, nickname 등 변수명 입력할 때마다 Profile.nickname 이런식으로 타입 바로바로 인식하는 것 같은데 전 인식을 못하는 것 같아요. 제가 코드를 잘못 작성한 부분이 있을까요?빨간줄 그어져 있어서 확인해보면 이렇게 뜨네요getProfileQuery.data를 콘솔에 찍으면위에 사진처럼 잘 나옵니다. 도와주시면 감사하겠습니다!!
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
Ios 시뮬레이터 아이콘
안녕하세요 강사님 강의 정말 잘 듣고있습니다. 안드로이드에선 잘되는데 IOS에선 아이콘이 잘뜨지 않아서요처음 부터 다시 해보기도하고 캐시도 삭제하고 실행해도 제대로 아이콘이 나오질 않네요x-code에서 다시 빌드할때 에러는아니고 워닝이 690개로 너무 많이 뜨는데 그거랑도 상관이 있을까요? 이유를 몰라서 해보다가 질문남깁니다.
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
안녕하세요. 추가 기능 관련 문의드립니다.
안녕하세요. Kyo 강사님최근 강의를 듣고 이것 저것 기능 추가하고 있습니다.#1 엑세스 토큰이 만료 된후에 재인증을 받아야 하는데요.1시간 지나면 인증이 풀리고 로그 아웃하고 다시 받아야 하네요..찾아보니 인터셉터라는 기능을 써서 401이냐 419 코드에 따라 처리 해야 하는 것 같은데요.401 일때는 리프래쉬 토큰이 있으면 자동으로 재인증 받고 처리419 코드 일 경우 메인 스크린으로 리다이렉트 되어야 할 것 같은데요.잘 안되네요.. 핵심 코드만 보고 적용 하기에는 아직 무리가 있습니다. #2. 구글 메세지 push 기능도 추가하고 있는데요.. FCM서버에서 메세지 전송 / 앱에서 받기 가르침 부탁드립니다. 혹시 참고 강의가 있을까요? 감사합니다.
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
ios 시뮬레이터에서 비밀번호(or 비밀번호 확인) 재 포커스 후 입력시 이전값이 초기화 됩니다
안드로이드에서는 초기화 문제 없는데 ios에서만 그러네요..ㅠ일단 오류 확인에 있어 필요하다는 코드 위주로 올렸는데 더 필요한 코드가 있다면 알려주세요! SignupScreen.tsximport {SafeAreaView, StyleSheet, Text, TextInput, View} from 'react-native'; import React, {useRef} from 'react'; import InputField from '../../components/InputField'; import useForm from '../../hooks/useForm'; import CustomButton from '../../components/CustomButton'; import {validateSignup} from '../../utils'; function SignupScreen() { const passwordRef = useRef<TextInput | null>(null); const passwordConfirmRef = useRef<TextInput | null>(null); const signup = useForm({ initialValue: {email: '', password: '', passwordConfirm: ''}, validate: validateSignup, }); const handleSubmit = () => { console.log(signup.values); }; return ( <SafeAreaView style={styles.container}> <View style={styles.inputContainer}> <InputField autoFocus placeholder="이메일" error={signup.errors.email} touched={signup.touched.email} inputMode="email" returnKeyType="next" // return키가 아닌 다른 키 옵션을 주고 싶을때 blurOnSubmit={false} // next와 같은 키를 눌러도 키가 닫히지 않음 (false) onSubmitEditing={() => passwordRef.current?.focus()} // next키를 눌렀을 때 다음 input으로 이동 {...signup.getTextInputProps('email')} /> <InputField key="password" ref={passwordRef} placeholder="비밀번호" textContentType="oneTimeCode" // ios에서 강력한 암호 뜨게 하는걸 방지 error={signup.errors.password} touched={signup.touched.password} secureTextEntry returnKeyType="next" blurOnSubmit={false} onSubmitEditing={() => passwordConfirmRef.current?.focus()} {...signup.getTextInputProps('password')} /> <InputField key="passwordConfirm" ref={passwordConfirmRef} placeholder="비밀번호 확인" textContentType="oneTimeCode" error={signup.errors.passwordConfirm} touched={signup.touched.passwordConfirm} secureTextEntry onSubmitEditing={handleSubmit} {...signup.getTextInputProps('passwordConfirm')} /> </View> <CustomButton label="회원가입" /> </SafeAreaView> ); } export default SignupScreen; const styles = StyleSheet.create({ container: { flex: 1, margin: 30, }, inputContainer: { gap: 20, marginBottom: 30, }, }); useForm.ts// 리액트 hook form 같은 리액트 라이브러리를 사용해도 괜찮지만 // 복잡하고 많은 input을 다루지 않기 때문에 직접 구현함 import {useEffect, useState} from 'react'; interface UseFormProps<T> { initialValue: T; validate: (values: T) => Record<keyof T, string>; } function useForm<T>({initialValue, validate}: UseFormProps<T>) { const [values, setValues] = useState(initialValue); const [touched, setTouched] = useState<Record<string, boolean>>({}); const [errors, setErrors] = useState<Record<string, string>>({}); const handleChangeText = (name: keyof T, text: string) => { setValues({ ...values, [name]: text, }); }; const handleBlur = (name: keyof T) => { setTouched({ ...touched, [name]: true, }); }; const getTextInputProps = (name: keyof T) => { const value = values[name]; const onChangeText = (text: string) => handleChangeText(name, text); const onBlur = () => handleBlur(name); return {value, onChangeText, onBlur}; }; useEffect(() => { const newErrors = validate(values); setErrors(newErrors); }, [validate, values]); useEffect(() => { console.log('values값 뭐뭐 들어왔는지 체크용: ', values); }, [values]); return {values, errors, touched, getTextInputProps}; } export default useForm; validate.tstype UserInformation = { email: string; password: string; }; function validateUser(values: UserInformation) { const errors = { email: '', password: '', }; // email이 올바른 이메일인지 검사하는 정규표현식 // 이 테스트를 통과하지 못할경우 if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(values.email)) { errors.email = '올바른 이메일 형식이 아닙니다.'; } if (!(values.password.length >= 8 && values.password.length < 20)) { errors.password = '비밀번호는 8~20자 사이로 입력해주세요.'; } return errors; } function validateLogin(values: UserInformation) { return validateUser(values); } function validateSignup(values: UserInformation & {passwordConfirm: string}) { const errors = validateUser(values); const signupErrors = {...errors, passwordConfirm: ''}; if (values.password !== values.passwordConfirm) { signupErrors.passwordConfirm = '비밀번호가 일치하지 않습니다.'; } return signupErrors; } export {validateLogin, validateSignup}; InputField.tsximport { Dimensions, Pressable, StyleSheet, Text, TextInput, TextInputProps, View, } from 'react-native'; import React, {ForwardedRef, forwardRef, useRef} from 'react'; import {colors} from '../constants'; import {mergeRefs} from '../utils'; interface InputFieldProps extends TextInputProps { disabled?: boolean; error?: string; touched?: boolean; } // 디바이스의 높이 가져옴 const deviceHeight = Dimensions.get('screen').height; const InputField = forwardRef( ( {disabled = false, error, touched, ...props}: InputFieldProps, ref?: ForwardedRef<TextInput>, ) => { const inputRef = useRef<TextInput | null>(null); // input부분이 아닌 error msg(View컴포넌트) 부분을 클릭해도 input에 포커스를 해주기 위함 (Pressable 컴포넌트로 먼저 감싸주고나서!) const handlePressInput = () => { inputRef.current?.focus(); }; return ( <Pressable onPress={handlePressInput}> <View style={[ styles.container, disabled && styles.disabled, touched && Boolean(error) && styles.inputError, ]}> <TextInput ref={ref ? mergeRefs(inputRef, ref) : inputRef} // false일 때는 편집 가능 editable={!disabled} placeholderTextColor={colors.GRAY_500} style={[styles.input, disabled && styles.disabled]} {...props} autoCapitalize="none" // 자동 대문자 방지 spellCheck={false} autoCorrect={false} /> {/* error 메세지가 있을 때만 해당 컴포넌트 표시하기 위해 string 타입을 Boolean으로 변경 */} {touched && Boolean(error) && ( <Text style={styles.error}>{error}</Text> )} </View> </Pressable> ); }, ); export default InputField; const styles = StyleSheet.create({ container: { borderWidth: 1, borderColor: colors.GRAY_200, padding: deviceHeight > 700 ? 15 : 10, }, input: { fontSize: 16, color: colors.BLACK, padding: 0, }, disabled: { backgroundColor: colors.GRAY_200, color: colors.GRAY_700, }, inputError: { borderWidth: 1, borderColor: colors.RED_300, }, error: { color: colors.RED_500, fontSize: 12, paddingTop: 5, }, }); common.tsimport {ForwardedRef} from 'react'; // input component를 만들어서 사용할 때 해당 컴포넌트에서 사용하는 ref와 외부에서 주입하는 ref를 둘 다 사용 가능하게 함 function mergeRefs<T>(...refs: ForwardedRef<T>[]) { return (node: T) => { refs.forEach(ref => { if (typeof ref === 'function') { ref(node); } else if (ref) { ref.current = node; } }); }; } export {mergeRefs}; 찾아보기도 하고 챗gpt에도 물어보고 해봤지만 도저히 모르겠어서 질문 남겨봅니다! 일단 회원가입 스크린 관련해서만 올리긴 했는데 로그인 화면에서도 마찬가지로 비밀번호 부분만 그런 현상이 발생하네요..ㅠ혹시나 해서 비밀번호 input 속성으로 secureTextEntry 전달하는거 없애보니까 이런 문제가 없긴한데 그렇다고 이걸 전달 안할 수도 없고..어찌해야 할까요?? 아니면 이건 코드가 아닌 ios 자체 문제일까요??
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
ANDROID STUDIO 버전
현재 ANDROID STUDIO가 Jellyfish 버전으로 다운로드 되는데 상관없을까요?
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
Using the first of multiple matching destinations 에러 해결방법!
--- xcodebuild: WARNING: Using the first of multiple matching destinations: { platform:iOS Simulator, id:D6FC302F-1EC1-4258-8FD4-4AA0049970DB, OS:17.5, name:iPhone 15 } { platform:iOS Simulator, id:D6FC302F-1EC1-4258-8FD4-4AA0049970DB, OS:17.5, name:iPhone 15 } ** BUILD FAILED ** 이러한 에러가 발생하며, 빌드가 되지 않습니다. 해결 방법을 알고 싶습니다!!! 검색해도 정보가 많지 않습니다 ㅠ
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
로그아웃할때 /server/uploads/index.html' 파일을 찾을수없다고 에러가 나오는데 어떻게해야할까요?
로그아웃 버튼을 클릭하면 Error: ENOENT: no such file or directory, stat '/Users/user/Documents/code/MatzipApp/server/uploads/index.html'이런 에러가 나오고있어서 uploads폴더에 Index.html파일을 추가하니까 에러는 안나오는데 index.html에 아무것도 안작성해도되나요?
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
"실행 오류" yarn start 실행후
r - reload the appd - open developer menui - run on iOSa - run on Androidinfo Opening the app on Android...info JS server already running.info Launching emulator...info Installing the app...> Task :gradle-plugin:compileKotlin UP-TO-DATE> Task :gradle-plugin:compileJava NO-SOURCE> Task :gradle-plugin:pluginDescriptors UP-TO-DATE> Task :gradle-plugin:processResources UP-TO-DATE> Task :gradle-plugin:classes UP-TO-DATE> Task :gradle-plugin:jar UP-TO-DATE> Task :gradle-plugin:inspectClassesForKotlinIC UP-TO-DATE> Task :app:buildCodegenCLI SKIPPED> Task :app:generateCodegenSchemaFromJavaScript SKIPPED> Task :app:generateCodegenArtifactsFromSchema SKIPPED> Task :app:generatePackageList> Task :app:preBuild> Task :app:preDebugBuild> Task :app:compileDebugAidl NO-SOURCE> Task :app:compileDebugRenderscript NO-SOURCE> Task :app:generateDebugBuildConfig UP-TO-DATE> Task :app:javaPreCompileDebug UP-TO-DATE> Task :app:checkDebugAarMetadata UP-TO-DATE> Task :app:generateDebugResValues UP-TO-DATE> Task :app:mapDebugSourceSetPaths UP-TO-DATE> Task :app:generateDebugResources UP-TO-DATE> Task :app:mergeDebugResources UP-TO-DATE> Task :app:createDebugCompatibleScreenManifests UP-TO-DATE> Task :app:extractDeepLinksDebug UP-TO-DATE> Task :app:processDebugMainManifest UP-TO-DATE> Task :app:processDebugManifest UP-TO-DATE> Task :app:processDebugManifestForPackage UP-TO-DATE> Task :app:processDebugResources UP-TO-DATE> Task :app:compileDebugJavaWithJavac UP-TO-DATE> Task :app:mergeDebugShaders UP-TO-DATE> Task :app:compileDebugShaders NO-SOURCE> Task :app:generateDebugAssets UP-TO-DATE> Task :app:mergeDebugAssets UP-TO-DATE> Task :app:compressDebugAssets UP-TO-DATE> Task :app:processDebugJavaRes NO-SOURCE> Task :app:mergeDebugJavaResource UP-TO-DATE> Task :app:checkDebugDuplicateClasses UP-TO-DATE> Task :app:desugarDebugFileDependencies UP-TO-DATE> Task :app:mergeExtDexDebug UP-TO-DATE> Task :app:mergeLibDexDebug UP-TO-DATE> Task :app:dexBuilderDebug UP-TO-DATE> Task :app:mergeProjectDexDebug UP-TO-DATE> Task :app:mergeDebugJniLibFolders UP-TO-DATE> Task :app:mergeDebugNativeLibs UP-TO-DATE> Task :app:stripDebugDebugSymbols UP-TO-DATE> Task :app:validateSigningDebug UP-TO-DATE> Task :app:writeDebugAppMetadata UP-TO-DATE> Task :app:writeDebugSigningConfigVersions UP-TO-DATE> Task :app:packageDebug UP-TO-DATE> Task :app:createDebugApkListingFileRedirect UP-TO-DATE> Task :app:installDebug FAILED38 actionable tasks: 2 executed, 36 up-to-dateinfo 💡 Tip: Make sure that you have set up your development environment correctly, by running react-native doctor. To read more about doctor command visit: https://github.com/react-native-community/cli/blob/main/packages/cli-doctor/README.md#doctorFAILURE: Build failed with an exception.* What went wrong:Execution failed for task ':app:installDebug'.> com.android.builder.testing.api.DeviceException: No connected devices!* Try:> Run with --stacktrace option to get the stack trace.> Run with --info or --debug option to get more log output.> Run with --scan to get full insights.* Get more help at https://help.gradle.orgBUILD FAILED in 5sinfo Run CLI with --verbose flag for more details.|후 실행이 안됩니다..어떻게 해야되나요?
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
[4-0] GoogleMap 연동하기 진행 중 구글맵에 오류가 발생 했습니다.
안녕하세요 강사님. 강의 잘 듣고 있습니다. :)강의 진행 중 구글맵을 띄우는 과정에서 ERROR react-native-maps: AirGoogleMaps dir must be added to your xCode project to support GoogleMaps on iOS. 라는 오류가 발생하는데요, 이 때문에 구글맵이 보이지 않아서 진행이 어려운 상태 입니다. 앞서 해당 강의에서 8분 가량 설명 해주신 부분은 모두 진행 하였는데요, 어떻게 하면 구글 맵을 띄울 수 있을까요?ㅜㅜ
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
로그인 api 요청 이후 getAccessToken ( /auth/refresh ) api 401 error
안녕하세여 강사님 강의 잘 듣고 있습니다.다름이 아니라 회원가입 및 로그인 api 요청 성공시 onSuccess 함수 로직에 있는queryClient.refetchQueries({ queryKey: [queryKeys.AUTH, queryKeys.GET_ACCESS_TOKEN], });이 코드로 getAccessToken ( /auth/refresh ) api 를 요청하고 있습니다. 여기서 문제는 getAccessToken 요청시 401 error 가 발생하고 있습니다. DB 에 회원가입으로 생성된 유저 데이터는 잘 생성된 상태이고 오타는 없어보입니다. ㅠㅠ 도와주세여 아래 이미지는 log 이미지입니다.
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
colors[theme]을 못읽는 이유
import React, {ReactNode} from 'react'; import { Pressable, StyleSheet, Text, PressableProps, Dimensions, View, StyleProp, ViewStyle, TextStyle, } from 'react-native'; import {colors} from '../../constants'; import useThemeStore from '@/store/useThemeStore'; import {ThemeMode} from '@/types/common'; interface CustomButtonProps extends PressableProps { label: string; variant?: 'filled' | 'outlined'; size?: 'large' | 'medium'; inValid?: boolean; style?: StyleProp<ViewStyle>; textStyle?: StyleProp<TextStyle>; icon?: ReactNode; } const deviceHeight = Dimensions.get('screen').height; function CustomButton({ label, variant = 'filled', size = 'large', inValid = false, style = null, textStyle = null, icon = null, ...props }: CustomButtonProps) { const {theme} = useThemeStore(); const styles = styling(theme); // 여기서는 제대로 출력이 됩니다. 값이 제대로 읽힙니다. console.log(colors[theme].PINK_700); return ( <Pressable disabled={inValid} style={({pressed}) => [ styles.container, pressed ? styles[`${variant}Pressed`] : styles[variant], inValid && styles.inValid, style, ]} {...props}> <View style={styles[size]}> {icon} <Text style={[styles.text, styles[`${variant}Text`], textStyle]}> {label} </Text> </View> </Pressable> ); } const styling = (theme: ThemeMode) => StyleSheet.create({ container: { borderRadius: 3, justifyContent: 'center', flexDirection: 'row', }, inValid: { opacity: 0.5, }, filled: { backgroundColor: colors[theme].PINK_700, }, outlined: { borderColor: colors[theme].PINK_700, borderWidth: 1, }, filledPressed: { backgroundColor: colors[theme].PINK_500, }, outlinedPressed: { borderColor: colors[theme].PINK_700, borderWidth: 1, opacity: 0.5, }, large: { width: '100%', paddingVertical: deviceHeight > 700 ? 15 : 10, alignItems: 'center', justifyContent: 'center', flexDirection: 'row', gap: 5, }, medium: { width: '50%', paddingVertical: deviceHeight > 700 ? 12 : 8, alignItems: 'center', justifyContent: 'center', flexDirection: 'row', gap: 5, }, text: { fontSize: 16, fontWeight: '700', }, filledText: { color: colors[theme].WHITE, }, outlinedText: { color: colors[theme].PINK_700, }, }); export default CustomButton; console.log(colors[theme].PINK_700); 이렇게 출력할 경우, 제대로 아래와 같이 출력이 됩니다만 스타일은 제대로 읽어오지 않습니다. 이 부분에 대해서 알고 싶습니다. BUNDLE ./index.js LOG Running "MatzipApp" with {"rootTag":171,"initialProps":{"concurrentRoot":false}} LOG light LOG #C63B64 LOG #C63B64 LOG #C63B64 ERROR TypeError: Cannot read property 'PINK_700' of undefined This error is located at: in CustomButton (created by ErrorBoundary) in RCTView (created by View) in View (created by ErrorBoundary) in ErrorBoundary (created by RetryErrorBoundary) in RetryErrorBoundary (created by RootNavigator) in RootNavigator (created by App) in EnsureSingleNavigator in BaseNavigationContainer in ThemeProvider in NavigationContainerInner (created by App) in _QueryClientProvider (created by App) in App in RCTView (created by View) in View (created by AppContainer) in RCTView (created by View) in View (created by AppContainer) in AppContainer in MatzipApp(RootComponent), js engine: hermes ERROR TypeError: Cannot read property 'WHITE' of undefined This error is located at: in RetryErrorBoundary (created by RootNavigator) in RootNavigator (created by App) in EnsureSingleNavigator in BaseNavigationContainer in ThemeProvider in NavigationContainerInner (created by App) in _QueryClientProvider (created by App) in App in RCTView (created by View) in View (created by AppContainer) in RCTView (created by View) in View (created by AppContainer) in AppContainer in MatzipApp(RootComponent), js engine: hermes ERROR TypeError: Cannot read property 'WHITE' of undefined This error is located at: in RetryErrorBoundary (created by RootNavigator) in RootNavigator (created by App) in EnsureSingleNavigator in BaseNavigationContainer in ThemeProvider in NavigationContainerInner (created by App) in _QueryClientProvider (created by App) in App in RCTView (created by View) in View (created by AppContainer) in RCTView (created by View) in View (created by AppContainer) in AppContainer in MatzipApp(RootComponent), js engine: hermes ERROR TypeError: Cannot read property 'WHITE' of undefined https://github.com/dydals3440/MatZip좀더 정확히 판단을 위하여 제가 커밋한 레포 남겨드립니다!!!
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
AWS S3 : 버킷에 사진이 업로드가 안됩니다(2)
[Nest] 27666 - 2024. 05. 23. 오후 12:23:25 ERROR [ExceptionsHandler] ENOENT: no such file or directory, stat '/Users/제이름/MatzipApp/server/uploads/index.html'Error: ENOENT: no such file or directory, stat '/Users/제이름/MatzipApp/server/uploads/index.html' 아까 올린 문제는 제가 지역을 잘못봐서 .env 파일에서 수정해서 해결했습니다. 다시 실행해보니 이번엔 저런 오류가 뜨는데욥실제로 저런 디렉토리랑 파일이 서버 하위에 없긴 합니다.. 구글링해도 도저히 답이 안나와서 다시 한번 질문 드립니다!
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
S3 실행시 버킷에 사진이 업로드가 안됩니다
기존에 있는 문제는 해결됐습니다!(개인정보가 있어서 삭제합니다ㅜㅜ)
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
회원가입 오류입니다!
일단 회원가입시 400 에러가 발생 합니다 ! 리퀘스트 인터셉터 에러 내용 {"adapter": ["xhr", "http", "fetch"], "baseURL": "http://localhost:3030", "data": {"email": "ajrfysd@naver.com", "password": "gsas22sgda"}, "env": {"Blob": [Function Blob], "FormData": [Function FormData]}, "headers": {"Accept": "application/json, text/plain, */*"}, "maxBodyLength": -1, "maxContentLength": -1, "method": "post", "timeout": 0, "transformRequest": [[Function transformRequest]], "transformResponse": [[Function transformResponse]], "transitional": {"clarifyTimeoutError": false, "forcedJSONParsing": true, "silentJSONParsing": true}, "url": "/auth/signup", "validateStatus": [Function validateStatus], "withCredentials": true, "xsrfCookieName": "XSRF-TOKEN", "xsrfHeaderName": "X-XSRF-TOKEN"}리스폰스 인터셉터 [AxiosError: Request failed with status code 400]email, password로그도 잘 찍히고 하는데 왜 400이발생하는지 모르겠습니다..ㅠㅠ 서버쪽 같기도 한데 잘 모르겠네요..postgresql에 테이블도 잘 생성 되어 있고 npm run start:devApplication] Nest application successfully started +2ms http://localhost:3030 크롬에서 3030 으로 요청시 로그에 내줄 index.html없다고 하는거 보니 작동 하는것 같긴 한데...이상하게 Postman 에서는 couldnot send 나오고.../auth/signup도 마찬가지고... 다른 부분은 confirmPassword를 제가 rePassword로바꾸었는데 보내는 쪽에서도 비밀번호확인은 안보내는것 같고 받는 쪽에서도 아예 안받는것 같은데..혹시 위 내용으로 추측 가능한 부분이 있을까요??
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
로그인/회원가입 오류 질문 드립니다.
const postLogin = async ({ email, password, }: RequestUser): Promise<ResponseToken> => { console.log('postLogin'); const {data} = await axiosInstance.post('/auth/signin', {email, password}); console.log('data', data); return data; };회원가입에서 오류가 발생해서 db를 봤는데 db에 데이터는 들어가 있습니다. 그래서 로그인을 진행해 봤는데 로그인이 되질 않아 postLogin에 console을 찍어 보았더니 axios post 에서 아무런 값도 받아오질 못하고 있었습니다. 오류 코드는 뜨지 않구요. 시뮬레이터를 껏다 켜보기도 하고 서버를 껏다 켜보기도 했는데 이제는 회원가입 시 db에 저장도 되질 않습니다.환경은 윈도우/안드로이드 입니다.https://github.com/ghgfhfg2/react-native-base
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
해결했습니다!
해결했습니다!
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
안드로이드에서만 테마별 색상이 적용안되는 이유
안드로이드 기기에서, 테마에 해당하는 색상을 못읽는 에러가 발생합니다!!iOS 같은 경우는 정상적으로 다크모드가 잘 동작합니다!!! 어떤 부분이 문제인지 알고 싶습니다. https://github.com/dydals3440/MatZip
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
useEffect 의존성 배열 문제
해당 강좌 그대로 진행하다가, 의존성 배열 문제로 인해 무한 렌더링이 발생했습니다.강사님의 깃허브 코드를 바탕으로, 강좌와 다르게 전역 상태로 관리를 진행하여 해결을 하긴 했습니다.어떠한 문제로 인해, 무한 렌더링이 발생되고, 이럴 경우에 어떤 방식으로 접근해서 해결하는지에 대한 접근 방식에 대해 알고 싶습니다!!!web과 다르게 RN은 디버깅하기가 생각보다 쉽지않네요... ㅠㅠ
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
의존성 배열에 filterItems를 넣으면 무한렌더링이 발생합니다.
import {useEffect, useState} from 'react'; import {queryKeys, storageKeys} from '@/constants'; import type {Marker} from '@/types'; import {getEncryptedStorage, setEncryptedStorage} from '@/utils'; import queryClient from '@/api/query-client'; const initialFilters = { RED: true, YELLOW: true, GREEN: true, BLUE: true, PURPLE: true, '1': true, '2': true, '3': true, '4': true, '5': true, }; function useMarkerFilterStorage() { const [filterItems, setFilterItems] = useState<Record<string, boolean>>(initialFilters); const set = async (items: Record<string, boolean>) => { queryClient.invalidateQueries({ queryKey: [queryKeys.MARKER, queryKeys.GET_MARKERS], }); await setEncryptedStorage(storageKeys.MARKER_FILTER, items); setFilterItems(items); }; const transformFilteredMarker = (markers: Marker[]) => { return markers.filter(marker => { return ( filterItems[marker.color] === true && filterItems[String(marker.score)] === true ); }); }; useEffect(() => { (async () => { const storedData = (await getEncryptedStorage(storageKeys.MARKER_FILTER)) ?? initialFilters; setFilterItems(storedData); })(); }, [filterItems]); return {set, items: filterItems, transformFilteredMarker}; } export default useMarkerFilterStorage;의도대로 items의 값을 set으로 변경하면 필터링이 정상적으로 동작하지만 무한렌더링이 발생합니다.무한 렌더링을 막기 위해 의존성 배열을 지우고 쿼리키를 무효화하는 방법등 많은 시도를 해봤지만 제대로 동작하지 않네요. 혹시 현재 진행된 강의에서 무한 렌더링을 해결할 수 있는 방법이 있을까요?
-
해결됨맛집 지도앱 만들기 (React Native + NestJS)
react-native-date-picker darkmode 적용 관련 공유
다크모드를 어떻게 적용시킬까 고민하다가, 찾아보니 theme이라는 프로퍼티를 사용해서 아래와 같이 코드를 작성하면 다크모드가 적용이 됩니다!! import {colors} from '@/constants'; import useThemeStore from '@/store/useThemeStore'; import {ThemeMode} from '@/types/common'; import React from 'react'; import { StyleSheet, View, Modal, SafeAreaView, Pressable, Text, } from 'react-native'; import DatePicker from 'react-native-date-picker'; interface DatePickerOptionProps { isVisible: boolean; date: Date; onChangeDate: (date: Date) => void; onConfirmDate: () => void; } const DatePickerOption = ({ isVisible, date, onChangeDate, onConfirmDate, }: DatePickerOptionProps) => { const {theme} = useThemeStore(); const styles = styling(theme); return ( <Modal visible={isVisible} transparent animationType="slide"> <SafeAreaView style={styles.optionBackground}> <View style={styles.optionContainer}> <View style={styles.pickerContainer}> <DatePicker mode="date" date={date} onDateChange={onChangeDate} locale="ko" theme={theme === 'dark' ? 'dark' : 'light'} /> </View> </View> <View style={styles.optionContainer}> <Pressable style={styles.optionButton} onPress={onConfirmDate}> <Text style={styles.optionText}>확인</Text> </Pressable> </View> </SafeAreaView> </Modal> ); }; const styling = (theme: ThemeMode) => StyleSheet.create({ pickerContainer: { alignItems: 'center', }, optionBackground: { flex: 1, justifyContent: 'flex-end', backgroundColor: 'rgba(0, 0, 0 / 0.5)', }, optionContainer: { borderRadius: 15, marginHorizontal: 10, marginBottom: 10, backgroundColor: colors[theme].GRAY_100, overflow: 'hidden', }, optionButton: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', height: 50, gap: 5, }, optionText: { color: colors[theme].BLUE_500, fontSize: 17, fontWeight: '500', }, }); export default DatePickerOption;