[React Native] Good To Know Things

2022. 1. 24. 03:49React Native/Basic


1. React Native Debugger

개발한 코드를 디버깅할 때 유용한 툴이다. 지금까지는 콘솔창을 이용해서 변수에 어떤 값이 들어가 있는지, 화면 전환 시 패싱된 파라미터값은 무엇인지 등을 확인했었는데 React Native Debugger를 통해서 좀 더 손쉽게 확인이 가능하다.

 

react native debugger는 stand alone app 이기 때문에 그냥 설치 파일 다운로드 후에 설치하고 실행하면 된다. 

https://github.com/jhen0409/react-native-debugger

 

GitHub - jhen0409/react-native-debugger: The standalone app based on official debugger of React Native, and includes React Inspe

The standalone app based on official debugger of React Native, and includes React Inspector / Redux DevTools - GitHub - jhen0409/react-native-debugger: The standalone app based on official debugger...

github.com

위의 깃헙 페이지에서 설치를 진행하면 되는데 난 따로 파일을 다운받지 않고 아래 명령어를 실행했다.

brew install --cask react-native-debugger

위 명령을 실행하면 응용프로그램에서 React Native Debugger가 자동으로 생기는데 실행시키면 된다. 이 툴 상에서 여러 가지 상태와 변수값들을 확인할 수 있는데 실행하면 아직 개발 중인 앱과 연결이 되지 않았다고 나온다. 시뮬레이터에서 연결할 수 있다. ios는 'command+d' 를 눌러 디버그 버튼을 누르면 된다. 안드로이드는 'command+m' 을 눌러 디버그 버튼을 누르면 된다.

연결이 잘 되고 오른쪽엔 콘솔창이 있고 왼쪽엔 action, state 등의 탭과 화면들이 있다.

사실 이 툴은 redux 개념을 배운 뒤에 쓰면 굉장히 유용하다. action, state는 중간중간 쓰기는 했지만 이게 redux 개념을 통해서 쓰이게 되는 것들이기 때문이다. 

 


2.  재사용 Component 생성

컴포넌트 - 뷰, 텍스트, 이미지, 버튼 등의 요소

 

이런 컴포넌트를 직접 만들 수 있다. 개발하는 앱의 identity가 있을 거다. 각 화면마다 공통적으로 들어가는 부분이 있을 텐데 identity에 맞게 템플릿을 만들어 두고 가져다 쓰면 굉장히 편하다.

 

재사용 가능한 컴포넌트를 만드는 것은 반복적으로 쓰게되는 템플릿을 마련해둔다고 생각하면 된다.

 

/src/utils/supertext.js 파일을 새로 만들고 템플릿을 만든다.

 

supertext.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {Component} from 'react';
import {
  SafeAreaView,
  ScrollView,
  StatusBar,
  StyleSheet,
  Text,
  useColorScheme,
  View,
} from 'react-native';

const Supertext = () => {
  return <Text style={styles.supertext}>This is my template</Text>;
};

const styles = StyleSheet.create({
  supertext: {
    backgroundColor: 'skyblue',
    fontSize: 25,
    color: 'blue',
    paddin: 15,
    width: 300,
  },
});

export default Supertext;

App.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {Component} from 'react';
import {
  SafeAreaView,
  ScrollView,
  StatusBar,
  StyleSheet,
  Text,
  useColorScheme,
  View,
} from 'react-native';

import {
  Colors,
  DebugInstructions,
  Header,
  LearnMoreLinks,
  ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
// import AnimOne from './src/Animation01';
// import AnimTwo from './src/Animation02';
import Supertext from './src/utils/supertext';

class App extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Supertext></Supertext>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#bbb',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;

supertext.js에서 만든 파일이 잘 출력된다. 그런데 여러 화면에서 쓰고 싶은데 텍스트가 정해져 있으면 활용하기 어렵다. 임의의 텍스트를 쓸 수 있어야 한다. App.js에서는 임의의 텍스트를 작성하고 supertext.js에서는 props로 받아온 뒤에 텍스트 태그 안에는 {props.children}을 받아오면 된다. props로 전달받은 Supertext 컴포넌트를 내부에서 사용할 때는 {props.children} 으로 접근 가능하다.

 

이번엔 스타일을 봐보자. 지금은 supertext.js의 스타일을 따르고 있는데 이 컴포넌트를 여러 화면에서 쓰고 싶은데 단 하나의 화면에서만 다른 스타일을 주고 싶을 때는 어떻게 할 수 있을까?

그냥 Supertext 에 style을 주면 어떻게 될까? - 반영이 안 된다. 이는 supertext.js에서 지정한 스타일을 리턴하고 있기 때문이다.
그럼 다른 스타일을 주려면 어떻게 하지? - spread operator를 쓴 props를 받아오면 된다. 그럼 Supertext에 준 style이 반영된다. 지정한 스타일을 제외한 다른 스타일은 다 날라갔다. 왜냐하면 supertext.js 에서 어떤 스타일을 지정했던지 간에 {...props}에 의해 전달받은 프로퍼티가 이미 존재하고 있는 프로퍼티를 덮어씌웠기 때문이다.
그럼 style에서 {...props} 와 다른 프로퍼티의 순서를 바꾸면 어떻게 될까? - 마지막에 오는 Supertext의 스타일을 따른다.

그렇다면 supertext.js에서 지정한 스타일을 따르되, App.js에서 한 가지 속성만 컨트롤하고 싶으면 어떻게 해야할까? - 아래 코드처럼 작성하면 된다. style은 styles.supertext를 따르되, props.style을 존중해주라는 의미이다. 다른 프로퍼티는 supertext.js의 css 속성을 따르게 되겠지만 App.js에서 backgroundColor를 red로 지정했기 때문에 배경색만 빨갛게 나올 것이다.

    style={[styles.supertext, props.style]}

 

supertext.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {Component} from 'react';
import {
  SafeAreaView,
  ScrollView,
  StatusBar,
  StyleSheet,
  Text,
  useColorScheme,
  View,
} from 'react-native';

const Supertext = props => {
  return (
    <Text 
    style={[styles.supertext, props.style]}
    // style={styles.supertext} 
    // {...props}
    >
      {props.children}
    </Text>
  );
};

const styles = StyleSheet.create({
  supertext: {
    backgroundColor: 'skyblue',
    fontSize: 25,
    color: 'blue',
    padding: 15,
    width: 300,
  },
});

export default Supertext;

 

App.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {Component} from 'react';
import {
  SafeAreaView,
  ScrollView,
  StatusBar,
  StyleSheet,
  Text,
  useColorScheme,
  View,
} from 'react-native';

import {
  Colors,
  DebugInstructions,
  Header,
  LearnMoreLinks,
  ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
// import AnimOne from './src/Animation01';
// import AnimTwo from './src/Animation02';
import Supertext from './src/utils/supertext';

class App extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Supertext style={{backgroundColor:'red'}}>
          This is my template!!!!!!!
        </Supertext>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#bbb',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;

 


3. Platform별 다른 코딩 구현

os 별로 다른 결과를 출력하거나 각 os 버전이 어떻게 되는지 알아보자.

App.js에서 react-native로부터 Platform을 import 한다. 그리고 세부 코드는 아래 코드를 참고하자.

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {Component} from 'react';
import {
  SafeAreaView,
  ScrollView,
  StatusBar,
  StyleSheet,
  Text,
  useColorScheme,
  Platform,
  View,
} from 'react-native';

import {
  Colors,
  DebugInstructions,
  Header,
  LearnMoreLinks,
  ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
// import AnimOne from './src/Animation01';
// import AnimTwo from './src/Animation02';
import Supertext from './src/utils/supertext';

class App extends Component {
  render() {
    console.warn(Platform.Version);
    return (
      <View style={styles.container}>
        <Supertext style={styles.div}>
          {/* This is my template!!!!!!! */}
          {Platform.OS === 'ios'
            ? 'This is my iOS Phone'
            : 'This is my Android Phone'}
        </Supertext>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#bbb',
    alignItems: 'center',
    justifyContent: 'center',
  },
  div: {
    ...Platform.select({
      ios: {
        backgroundColor: 'yellow',
      },
      android: {
        backgroundColor: 'red',
      },
    }),
  },
});

export default App;

아래는 위 코드의 실행 결과로 각각의 플랫폼, 버전, 배경색 지정 결과이다.

 

이번에는 플랫폼마다 특정 버전 이하면 지원하지 않는다는 문구를 띄우고 아니면 정상동작하는 코드를 짜보자.

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {Component} from 'react';
import {
  SafeAreaView,
  ScrollView,
  StatusBar,
  StyleSheet,
  Text,
  useColorScheme,
  Platform,
  View,
} from 'react-native';

import {
  Colors,
  DebugInstructions,
  Header,
  LearnMoreLinks,
  ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
// import AnimOne from './src/Animation01';
// import AnimTwo from './src/Animation02';
import Supertext from './src/utils/supertext';

class App extends Component {
  checkSupport = () => {
    if (Platform.OS === 'ios') {
      if (Platform.Version < 16.4) {
        return false;
      }
    } else {
      if (Platform.Version < 27) {
        return false;
      }
    }
    return true;
  };

  render() {
    console.warn(Platform.Version);
    return (
      <View style={styles.container}>
        {this.checkSupport() ? (
          <Supertext style={styles.div}>
            {/* This is my template!!!!!!! */}
            {Platform.OS === 'ios'
              ? 'This is my iOS Phone'
              : 'This is my Android Phone'}
          </Supertext>
        ) : (
          <Text>Sorry. Your phhone is not being supported by the app.</Text>
        )}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#bbb',
    alignItems: 'center',
    justifyContent: 'center',
  },
  div: {
    ...Platform.select({
      ios: {
        backgroundColor: 'yellow',
      },
      android: {
        backgroundColor: 'red',
      },
    }),
  },
});

export default App;

해당 버전 이하에 해당하기 때문에 지원하지 않는다는 문구가 떴다.

 

이처럼 react native는 ios와 안드로이드 둘 다 다루기 때문에 있는 기능으로 상황에 따라 잘 사용하면 된다.


4. Dimensions

화면의 크기 등을 알아보기 위한 방법으로 굉장히 간단하다. 아래 명령어를 실행하면 된다.

    console.warn('Screen', Dimensions.get('screen'));
    console.warn('Window', Dimensions.get('window'));

ios에서는 스크린과 윈도우의 height와 width가 모두 똑같지만 안드로이드는 width 값은 똑같지만 height 값이 다르다. 안드로이드는 화면 하단에 soft menu bar(soft navigation bar)가 있어서 그렇다. 윈도우의 경우는 이 soft menu bar를 제외한 크기를 출력하고 스크린의 경우 화면 전체의 크기를 출력한다.

 

그럼 Dimensions를 통해서 우리가 할 수 있는 건 뭐가 있을까? - 주목해야 할 것은 fontScale이다. 극히 드물 수 있지만 사용자가 단말기 설정에서 디바이스 전체 fontScale을 바꿀 수 있게 된다. 그럼 우리가 개발하는 앱의 크기나 모양이 틀어질 수도 있다. 그럼 유저에게 fontScale을 원래대로 돌려놓으라는 에러 메시지를 보여줘야 할 것이다. 아래 코드와 같이 사용할 수 있다.

 

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, {Component} from 'react';
import {
  SafeAreaView,
  ScrollView,
  StatusBar,
  StyleSheet,
  Text,
  useColorScheme,
  Platform,
  View,
  Dimensions,
} from 'react-native';

import {
  Colors,
  DebugInstructions,
  Header,
  LearnMoreLinks,
  ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
// import AnimOne from './src/Animation01';
// import AnimTwo from './src/Animation02';
import Supertext from './src/utils/supertext';

class App extends Component {
  functionA = () => {
    if (Dimensions.get('window').fontScale === 1){
      console.warn('Good')
    } else{
      console.warn('Error!! The Font scale must be 1')
    }
  }
  checkSupport = () => {
    if (Platform.OS === 'ios') {
      if (Platform.Version < 16.4) {
        return false;
      }
    } else {
      if (Platform.Version < 27) {
        return false;
      }
    }
    return true;
  };

  render() {
    // console.warn(Platform.Version);
    console.warn('Screen', Dimensions.get('screen'));
    console.warn('Window', Dimensions.get('window'));

    return (
      <View style={styles.container}>
        {this.functionA()}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#bbb',
    alignItems: 'center',
    justifyContent: 'center',
  },
  div: {
    ...Platform.select({
      ios: {
        backgroundColor: 'yellow',
      },
      android: {
        backgroundColor: 'red',
      },
    }),
  },
});

export default App;

 


5. Device 정보 가져오기

https://github.com/react-native-device-info/react-native-device-info

 

GitHub - react-native-device-info/react-native-device-info: Device Information for React Native iOS and Android

Device Information for React Native iOS and Android - GitHub - react-native-device-info/react-native-device-info: Device Information for React Native iOS and Android

github.com

 
API 쪽에 표가 나와있다. 메소드 이름과 리턴 타입이 적혀있고 OS나 환경별로 지원이 되는지 안 되는지를 알 수 있다. 안드로이드는 대부분 지원이 되는데 ios는 지원되지 않는 게 꽤 있다.
이 라이브러리를 사용하기 위해 깃헙페이지의 installation을 보고 설치를 따라하자.
npm install --save react-native-device-info
cd ios
pod install
cd ..

 

설치를 다 하면 깃헙페이지의 Usage 쪽에 안내를 따른다.

import DeviceInfo from 'react-native-device-info';

 

그리고 API에 나와있는 getBrand()를 한 번 써보자.

    console.warn(DeviceInfo.getBrand());
    console.warn(DeviceInfo.isTablet());
getBrand() - 시뮬레이션 기계의 브랜드 리턴. ex) ios - Apple
isTablet() - 태블릿인지 아닌지 boolean 리턴

참고 자료

https://www.inflearn.com/course/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8C-%EA%B8%B0%EC%B4%88/dashboard

 

iOS/Android 앱 개발을 위한 실전 React Native - Basic - 인프런 | 강의

Mobile App Front-End 개발을 위한 React Native의 기초 지식 습득을 목표로 하고 있습니다. 진입장벽이 낮은 언어/API의 활용을 통해 비전문가도 쉽게 Native Mobile App을 개발할 수 있도록 제작된 강의입니다

www.inflearn.com