리액트 네이티브 2,3

송은우·2022년 1월 27일
0

ts와 js의 관계 : js 변수, 매개변수, 리턴값에 타입이 붙어 있다. 브라우저나 노드는 JS 실행 가능, TS는 불가능. 따라서 TS를 JS로 바꾸는 과정 필요
TS의 장점은 실행시 타입이 제거됬지만, 코딩시 조금 더 오타, 자동완성이 좀 잘 됨.

type RootStackParamList = {
  Home: undefined;
  Details: undefined;
};
type HomeScreenProps = NativeStackScreenProps<RootStackParamList, 'Home'>;
type DetailsScreenProps = NativeStackScreenProps<ParamListBase, 'Details'>;

파라미터가 없으면 undefined로 처리함.
리턴값은 타입 지정 안 하는 경우는 너무 명확한 경우인 것들은 생략 가능함.
리액트 navigation 은 safe area view를 자동으로 처리해줌.
Stack.Navigator이라고 적는 이유는 page를 왔다 갔다 하는 것들이 stack처럼 된다. Tab, drawer같은 여러가지 것들이 있음. Pressable, TouchableWithoutFeedback을 쓰는 이유는 IOS, android 화면을 같게 하기 위해서 임.
navigation.push("Home");를 통하면 stack 방식처럼 history같은 느낌임. navigation.goBack으로 과거로 이동

bottom tab, drawer, 여러 개를 같이 쓸 수도 있음

export type LoggedInParamList = {
  Orders: undefined;//주문 화면
  Settings: undefined;//세팅 화면
  Delivery: undefined;//배달 화면
  Complete: {orderId: string};//완료 화면
  //complete 에 string인 orderId를 파라미터로 넣음 
};

export type RootStackParamList = {
  SignIn: undefined;
  SignUp: undefined;
};

각각의 페이지를 props로 전달해버림.
파마리터는 다른 화면에서 전달받을 만한 것을 파라미터로 처리함.
값에 따라 바뀔 부분들.
나눠 놓는 것의 장점. 로그인 전후를 비교하는 것들이 쉬움. 회원가입을 안 뜨도록 조금 더 세밀하게 설정해줌.
타입을 import, export가 가능함.

지도 위에 Stack으로 쌓아서 완료 처리화면을 완료했다가, 마지막으로 지도로 돌아오는 방식을 쓰는게 목표임. 지도는 로딩시 비용이 큼
중첩된 Navigator을 잘 설계하는 것이 중요함
탭은 왔다갔다 해도 남아 있을 수 있고, 아닐 수도 있음. 그냥 다 직접 해보기
Screen을 하나로 안 묶으면 에러가 날 수 있는데, Tab.Group으로 묶는 것들이 좋을 수 있음.

style={!email || !password ? styles.loginButton : [styles.loginButton, styles.loginButtonActive]}

//StyleSheet.compose(styles.loginButton, styles.loginButtonActive)
//이것과 동일하긴 함.
          

이 배열은 2개의 css를 합쳐줌.

const onChangeEmail = useCallback(text => {
    setEmail(text);
  }, []);

onChange할 때 e로 처리하는 과정이 없어도 됨.

const canGoNext = email && password;

이런 식으로 변수 자체를 주석처럼 사용해 처리하는 것이 좋음
핸드폰으로 하는 것은 최소 30~40 이상 단위로 해주는게 좋음. 이유는 핸드폰 터치라서

 //borderBottomWidth: 0.5,
    borderBottomWidth: StyleSheet.hairlineWidth,

이런 식으로 최소 단위 1보다 작은 선을 만들고 싶을 때 StyleSheet자체 단위가 있음

importantForAutofill="yes"
autoComplete="email"
textContentType="emailAddress"

이게 자동 완성 기능 사용할 수 있도록 하는 방법. samsung pass같은 것들

autoComplete에 담을 수 있는 내용이 생각보다 다양하다.
sms-otp같은 것도 가능함
공식문서에 있는 점 찍혀 있는 것들은 IOS, android에서만 되는 경우기 때문에 주의할 필요는 있음.

returnKeyType="next"로 바꿀 수 있고, 이런 것들을 다 하나하나 수정 가능함.

  const emailRef = useRef<TextInput | null>(null);
  const passwordRef = useRef<TextInput | null>(null);

ref에도 타입 지정 해야됨.

returnKeyType="next"
          onSubmitEditing={() => {
            passwordRef.current?.focus();
          }}
          ref={emailRef}
          value={email}
          style={styles.textInput}
          placeholder="이메일을 입력해주세요."
          onChangeText={onChangeEmail}
          importantForAutofill="yes"
          autoComplete="email"
          textContentType="emailAddress"
          returnKeyType="next"
          onSubmitEditing={() => {
            passwordRef.current?.focus();
          }}
          blurOnSubmit={false}
          ref={emailRef}

이렇게 처리해야 됨.
blurOnSubmit은 엔터 누를시 키보드가 내려갔다 오는 것 막는 것.

키보드에 가려져서 인풋 창이 안 보이는 것(Keyboard Avoiding View), 인풋 밖 누르면 키보드 내려가는 것 , 등

<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>

accessible은 시각장애인용 스크린 리더기를 위해 이 부분을 읽지 않도록 accessible로 설정해주는 것.

keyboardavoidingview는 생각보다 까다로움. 모두 다 적용해버리면 쓸데없이 올라가게 되고, 사용할 때는 항상 behavior를 처리해야됨. position은 android에서 잘 되고, padding은 ios에서 잘 되는 부분임. height,padding은 안드로이드상에서 안됨.

behavior={Platform.OS === 'android' ? 'position' : 'padding'}>
이런 것도 가능함.
keyboardAvoidingView가 생각보다 별로기에
npm I react-native-keyboard-aware-scrollview
를 써버림

StyleProp<ViewStyle>

리액트 스타일에 관한 styleSheet는 이렇게 적는다고 암기.
View와 Text에 관한 Style을 저렇게 적을 수 있음

import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scrollview';
보면 에러가 나있음.
그거는 ts가 아닌 js로 작성된 라이브러리라서 누군가가 그렇게 세팅을 해뒀는지 보려면 @types/라이브러리명
이렇게 해서 패키지를 직접 만들어서 쓸 수도 있음

타입 지원이 안되기에
react-native-keyboard-aware-scrollview.d.ts
파일로 직접 만들어서 넣어줘야됨.
TypeScript로 시작하는거는 KeyboardAvoidingView에서 시작한거기에, Keyboard Avoiding View의 타입으로부터 대충 긁어와서 시작하는 방법으로 함.
redux tool kit.

const store = configureStore({
  reducer: rootReducer,
  middleware: getDefaultMiddleware => {
    if (__DEV__) {
      const createDebugger = require('redux-flipper').default;
      return getDefaultMiddleware().concat(createDebugger());
    }
    return getDefaultMiddleware();
  },
});
export default store;

reducer를 flipper를 사용하기 위해서 reducer를 쓰게 됨. 없으면 그냥 대충 해도 됨.

slice가 모여서 reducer가 되고, reducer가 모여서 store가 된다는 느낌. provider에 store가 됨.
리덕스도 context API를 사용했기 때문에 결과적으로 내부적으로 context API를 쓰긴 함.

profile
학생의 마음가짐으로 최선을 다하자

0개의 댓글