728x90
반응형

내가 보려고 작성하는 typescript 정리

 

1. 배열에서 객체의 타입을 지정해주기

 

json파일에서 가져온 배열의 객체 타입을 따로 타입을 지정하는데 어려움이 있어

type CountryType = (typeof Countries)[number];

이런 방식으로 해결했다.

 

2. NonNullable ts util 사용하기

 

NonNullable ts util을 사용하면 파라미터값의 type을 따로 지정해주지않아도된다.

 

참고

 

https://www.typescriptlang.org/docs/handbook/utility-types.html

 

const onChangeText: NonNullable<TextInputProps['onChangeText']> = text => {
setEnable(text.length > 9);
updateInputs({tel: text});
};
728x90
반응형
728x90
반응형

개발중인 RN 앱에 react-native-vision-camera 를 적용했는데, ios 빌드가 되지 않았다

 

에러 내용은 xcode로 확인해봤을때

 

No member named 'ShareableValue' in namespace 'reanimated'

 

로 확인할 수 있었다.

 

npm 이슈탭에서 찾다보니

 

"react-native-reanimated": "^3.1.0",

해당 라이브러리가 3버전부터는 

"react-native-vision-camera": "^2.15.4",

에서 사용하는 name space를 제공하지 않는다는 것을 알게 됐고

 

"react-native-reanimated": "2.15.0",
"react-native-vision-camera": "^2.15.4",

로 버전을 맞추니 정상 빌드됐다.

 

주의했던 점은 앱내에서 사용하고 있는

"react-native-reanimated-carousel": "^3.3.2",

 

"react-native-reanimated": "2.15.0",

 

의 2.0.0 버전 이상이어야 된다는 docs를 보고 해당 버전을 2버전중 최고버전으로 세팅했다.

 

728x90
반응형
728x90
반응형

 

Xcode 로 종종 ios 를 열때, indexing processing files 에서 계속 멈춰있는 경우가 있다.

 

이는 /Xcode/DerivedData 를 삭제하면 해결된다

 

미리 빌드된 모듈이 충돌되서 그런듯하다

 

명령어는

 rm -rf ~/Library/Developer/Xcode/DerivedData 

 

또는

 

cd /Users/사용자명/Library/Developer/Xcode/DerivedData
rm -rf *

 

다시 xcode 실행하면 정상작동한다.

728x90
반응형
728x90
반응형

정말 간단하지만 RN에서 꼭 필요한 lib중에 한 4,5년전쯤에 나온 라이브러리들이 있다.

해당 library들은 readMe 에보면 compile .. 등으로 dependcies에 가져온다.

compile, runtime, testCompile, testRuntime 은 Gradle 4.10 (2018.8.27) 이후로 deprecate 되었다.
그리고 Gradle 7.0 (2021.4.9) 부터 삭제되었다.

 

예전 라이브러리들의 

compile -> implementation

runtime -> runtimeOnly

testCompile -> testImplementation

testRuntime -> testRuntimeOnly

 

등으로 수정해주면 된다.

728x90
반응형
728x90
반응형

사실 3년 좀 넘게 RN을 통해 앱을 개발하면서, 

종종 겪는 에러였다.

ios는 뭔가 android보다 항상 좀더 까다로운 느낌을 받는다.

 

IOS에서는 https 만 사용할 수 있도록 보안정책이 되어있기때문에

현재 http로 시작하는 api를 따로 설정해줘야한다

 

최종 info.plist는

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>api.base.url</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>

 

728x90
반응형
728x90
반응형

샘플앱을 안드로이드 버전만 요구하시다가, 급하게 ios 버전도 필요하시다는 말씀을 듣고나서

라이브러리들의 ios 세팅들을 하고있다.

 

env파일 android 세팅은 정말 한번에 끝냈지만, ios env세팅은 정말 힘들었다.

 

일단,

추가되어있는 env파일 들이다.

 

xcode의 프로젝트에서 우클릭 후, new file로  Config.xcconfig 을 생성한다.

해당파일에 

#include? "tmp.xcconfig"

를 추가해준다.

 

Product -> Scheme -> New Scheme 으로, dev / prodcution을 생성해준다.

 

Edit Scheme -> Build -> Pre-action 에 새로운 run script를 생성함으로써 적용할 수 있다.

내경우 .env가 release / .env.debug 가 dev환경이다.

 

따라서 dev 의 pre-action에는 

rm "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}"
echo ".env" > /tmp/envfile

"${SRCROOT}/../node_modules/react-native-config/ios/ReactNativeConfig/BuildXCConfig.rb" "${SRCROOT}/.." "${SRCROOT}/tmp.xcconfig"

 

production의 pre-action에는

 

rm "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}"
echo ".env.debug" > /tmp/envfile

"${SRCROOT}/../node_modules/react-native-config/ios/ReactNativeConfig/BuildXCConfig.rb" "${SRCROOT}/.." "${SRCROOT}/tmp.xcconfig"

를 작성해줬다.

 

xcode 로 빌드를 했더니

 

Please verify your .env file is correctly formatted.

라는 에러가 나왔는데,

이는 .env파일에 주석처리 되어있던 부분을 xcode에서 형식이 잘못되어있다고 읽어서 생긴 문제였다.

 

env에 있는 주석/한글 제거하고 하니 해결

728x90
반응형
728x90
반응형

샘플앱을 만들면서 안드로이드 apk만 필요하시다는 요구사항이 있어서, 급하게 프로젝트를 마무리했는데,

IOS 버전도 testflight를 통해 접근할 수 있도록 부탁한다는 요청사항을 받았다.

 

급하게 라이브러리들의 ios세팅을 마치고

xcode로 빌드를 하려는데

 

해당 에러가 나왔다.

xcode 버전을 내리라는 stackoverflow 의 답변들도 있었지만

 

cd ios && pod cache clean --all && pod install && cd ..

 

로 해결.

 

물론 메트로도 재시작했다.

 

RN을 하다보면 ./gradlew clean과 pod cache clean -all 을 자주 사용하는 것같다

728x90
반응형
728x90
반응형

디버그 / 릴리즈 모드에 따른 api를 __DEV__ 로 분리하곤 했는데,

이번에 회사에서 요구한 샘플앱에는 env 파일로 적용했다.

 

먼저 

 

yarn add react-native-config

로 react-native-config 세팅을 해준다.

 

docs에 나온것 처럼

 

project/android/app/build.gradle

 

 

project.ext.envConfigFiles = [
    debug: ".env.debug",
    release: ".env",
    anothercustombuild: ".env.staging",
]

apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle" // 추가


defaultConfig {
	        resValue "string", "build_config_package", "AndroidManifest파일 packageName입력" // 추가
            ...
}

 

등을 추가해준다.

 

해당 파일을 설치해주고, 

 

파일별로 

BASE_URL="base url";

을 추가해준뒤

import Config from 'react-native-config';
console.log('Config.BASE_URL ::::::' + Config.BASE_URL);

 

yarn android

 

react-native run-android --variant=release

 

로 dev일때, release일때 확인해보면 된다.

728x90
반응형
728x90
반응형

VScode로 코딩을 치고있는데, 자꾸 jsx return 컴포넌트 들에 붉은 에러 줄이 표시됐다.

물론 컴파일엔 문제가 없어서 vsCode문제겠거니 하고있었는데, 

그냥 눈이 편하게 하기위해 붉은 에러줄을 없애기로 했다.

 

tsconfig.json 에 가보니

 

{
"extends": "@tsconfig/react-native/tsconfig.json",
}

덩그러니 한줄만 있었고, 붉은 줄이 표시되고있었다.

 

해당 key-value의 에러 메세지는 file '@tsconfig/react-native/tsconfig.json' not found.

 

이었고,

"jsx": "react-jsx"

를 밑에 추가해주니, 

 

'jsx' should be set inside the compilerOptions 라는 붉은 줄이 나왔다.

tsconfig.json을 

{
"extends": "@tsconfig/react-native/tsconfig.json",
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"jsx": "react"
}
}

로 수정해주고

 

VScode를 재시작하니 해결

 

728x90
반응형
728x90
반응형

지금까지 RN 프로젝트를 해오면서, 짧은 개발기간을 핑계로 많은 상태관리 라이브러리가 있으면서

익숙하던 redux를 항상 고집해왔다.

zustand와 mobx도 실무에서 많이 사용하는 걸로 알고있는데

항상 무엇인가 가벼운(?) 프로젝트에서 많이 사용한다는 잘못된 선입견이 생겨서인지

신규 프로젝트를 구상할때 항상 redux / asyncstorage / persist-store 들로 상태관리를 했다.

 

성장하지 않는 느낌이 들어서, 이번에 짧은 개발기간임에도 불구하고, 이꽉물고 새로운 상태관리를 적용해보려했다.

결과적으로 말하자면 redux를 사용할때보다 보일러 플레이트가 현저히 줄어서, 코드 치기가 쉬웠다.

 

이번 글에선 react-native cli로 생성한 프로젝트에 mobx 를 적용하는 간단한 설명을 메모해 두려고한다.

항상 새로운 라이브러리를 쓴다는건 신나는 일이고, 결국엔 거의 비슷한 로직으로 돌아간다는게 참 재밌는거 같다.

 

당연히 mobx도, redux처럼 여러개의 store를 사용할수있고(redux에서 여러개의 reducer를 root reducer로 합치는 것과 동일)

하나의 store에 여러값을 저장 할 수 있다.

 

yarn add mobx                                                                             
yarn add mobx-react

 

일단 mobx 와 mobx-react 를 프로젝트에 import 해준다

( mobx-react-lite를 임포트 해주라는 글들도 있지만, mobx-react-lite 내가 적용할때는 babel쪽 syntax에러가 많이 발생해서

mobx-lite를 import해 줬다.)

 

기본 구조

hooks/useRootData.js 는 mobx를 쓰는 hook으로

 

소스코드는

import {useObserver} from 'mobx-react';
import React, {useContext} from 'react';
import {storesContext} from '../utils/context';

export const useStoreData = (context, storeSelector, dataSelector) => {
const value = useContext(context);
if (!value) {
throw new Error('No store');
}
const store = storeSelector(value);

return useObserver(() => {
return dataSelector(store);
});
};

export default dataSelector => {
return useStoreData(storesContext, contextData => contextData, dataSelector);
};

 

import {observable, runInAction} from 'mobx';

const createStore = () => {
const anotherStore = {
anotherKey: observable.box('anotherKey'),
changeAnotherKey: data =>
runInAction(() => anotherStore.anotherKey.set(data)),
};

return anotherStore;
};

const anotherStore = createStore();
export default anotherStore;

 

import {observable, runInAction} from 'mobx';

const createStore = () => {
const loginInfoStore = {
loginInfo: observable.box('userName'),
changeLoginInfo: data =>
runInAction(() => loginInfoStore.loginInfo.set(data)),
connect: observable.box(true),
changeConnect: data => runInAction(() => loginInfoStore.connect.set(data)),
};

return loginInfoStore;
};

const store = createStore();
export default store;

 

import loginInfoStore from './loginInfoStore';
import anotherStore from './anotherStore';

const createRootStore = () => {
return {
loginInfoStore,
anotherStore,
};
};

export default createRootStore;
import {useLocalObservable} from 'mobx-react';
import React, {createContext} from 'react';

import createRootStore from '../store/index';

export const storesContext = createContext(null);

export const StoreProvider = ({children}) => {
const store = useLocalObservable(createRootStore);

return (
<storesContext.Provider value={store}>{children}</storesContext.Provider>
);
};

이 소스코드들을 두가지 store에 한스토어당 2가지이상을 세팅하는 예제로 사용하면 된다.

 

상태값을 사용하고 싶은 component에서

 

const {loginInfo, changeLoginInfo, connect, changeConnect, anotherKey} =
useStoreData(({loginInfoStore, anotherStore}) => ({
loginInfo: loginInfoStore.loginInfo.get(),
changeLoginInfo: loginInfoStore.changeLoginInfo,
connect: loginInfoStore.connect.get(),
changeConnect: loginInfoStore.changeConnect,
anotherKey: anotherStore.anotherKey.get(),
}));

해당 hook으로 state, setState 값을 선언해주고

 

changeConnect(!connect);

이런식으로 사용해주면된다.

 

이번 프로젝트에 mobx의 기본 구조를 적용하면서, 내가 redux-saga / redux-thunk 등의 미들웨어가 mobx에서 어떻게 적용되는지,

mobx의 persist-store적용은 어떻게 하는지 등에 대해 궁금증이 생겼다. 

 

개발은 참 재미있다.

728x90
반응형

+ Recent posts