[React Native] 강의 목표 앱 만들기

kya·2022년 10월 5일
0

TIL

목록 보기
2/2
post-thumbnail

Tips

1. babel.config.js 코드의 module.exports는 ES6 문법으로 수정하지 않는다.


2. 새로운 상태가 이전 상태에 의존하는 경우, 업데이트하는 가장 좋은 방법

  • 상태 변화 함수 안에서 기존 상태를 가지고 업데이트를 하는 콜백 함수를 사용하는 것이다.
    setCourseGoals((prev) => [enteredGoal, ...prev]);
  • 이 콜백 함수는 React에서 제공하는 것으로, 자동으로 기존 상태를 준다.
  • React 공식 문서에서도 이 방법으로 설명하고 있다.

3. iOS에서는 Text 컴포넌트의 boderRadius가 적용되지 않는다.

  • Text를 View 컴포넌트로 감싸서 해결할 수 있다.

4. CSS와 달리 스타일 상속이 적용되지 않는다.

  • View에 color 속성을 주더라도, 자식으로 있는 Text에 반영되지 않는다.

5. Touchable 컴포넌트는 모두 Pressable 컴포넌트로 대체되었다.


6. Pressable 컴포넌트의 style 속성에는 StyleSheet 객체 대신 함수를 사용할 수 있다.

<Pressable
    style={({ pressed }) => pressed && styles.pressedItem}
    android_ripple={{ color: "#210644" }}
    onPress={() => onDelteGoal(id)}
  >
  • 이 함수는 터치 상태가 변할 때마다 호출된다.
  • 이 함수는 자동으로 매개변수로 터치 상태 데이터를 주며, 해당 데이터 안의 pressed 값은 터치 여부를 가지고 있다.

7. expo-status-bar에서 StatusBar 컴포넌트를 사용해서 스타일을 변경할 수 있다.

<StatusBar style='light'/>

8. React Native에서 React 개발자 도구를 사용하는 방법

  • RN에서 React 개발자 도구를 사용하기 위해서는 따로 설치를 해줘야 한다.
yarn global add react-devtools

react-devtools


기본 컴포넌트

1. View

  • RN에서는 각 컴포넌트마다 명확한 용도가 있다.
  • View 컴포넌트 안에 텍스트를 넣으면 어떻게 될까?
    <View style={styles.container}>Hello World</View>
  • 텍스트 문자열은 Text 컴포넌트 안에 넣어야 한다는 에러가 발생한다.
  • 웹에서는 div, section 등 다양하지만, RN에서는 View가 콘텐츠를 담는 컨네이너 역할을 하는 유일한 컴포넌트이다.

2. Text

  • 텍스트 문자열을 넣어야 할 때 사용한다.
    <Text>List of goals...</Text>

3. Button

  • 웹의 HTML과는 다르게 모든 컴포넌트를 import 해주어야 한다.
  • Button 컴포넌트는 열린 태그와 닫힌 태그 형식으로 사용하지 않고, 다음과 같이 사용한다.
  • Button은 style 속성 적용이 불가능하다.
    <Button title='Tap me!' />

4. TextInput

  • HTML의 input과 사용 방식은 동일하다.
    <TextInput placeholder='Your course goals!' />

5. Image

  • HTML의 img 태그와는 달리 source 속성에 require 함수를 통해 이미지를 가져온다.
    <Image style={styles.image} source={require("../assets/images/original.jpeg")} />


스타일링

1. React Native에는 CSS가 없다.

  • 브라우저가 아니기 때문에, CSS 코드를 작성할 수 없기 때문이다.
  • 대신 JavaScript 코드로 style 속성을 적용한다.
  • 인라인 방식보다는 StyleSheet 객체를 사용하는 것이 좋다.

2. 모든 컴포넌트에 style 속성이 가능한 것은 아니다.

  • Button 컴포넌트는 불가능하다.
  • Button에는 color 속성을 통해 색상 변경은 가능하다.
  • 스타일링 Button을 만들고 싶다면, Pressable, View, Text 컴포넌트를 사용해서 커스텀해야 한다.

3. px가 기본 단위이기 때문에, 생략이 가능하다.


4. border 속성

  • 일반적으로 사용하는 border처럼 한 줄에 적용할 수 없다.
    <Text style={{ borderWidth: 1, borderColor: "red" }}>Hello World</Text>
  • borderColor에는 문자열 값만 넣을 수 있다.

5. Flexbox

  • CSS에서의 Flexbox와 비슷하지만, 조금씩 다른 부분들이 있다.
    container: {
      flex: 1,
      flexDirection: "row"
      justifyContent: "flex-start",
      alignItems: "flex-start",
    }
  • flex: 1은 컨테이너 내에서 사용할 수 있는 모든 공간을 차지하도록 확장하는 속성이다.
  • RN에서는 flexDirection의 기본값이 column이다.
  • RN에서는 alignItems의 기본값은 stretch이다. stretch는 쭉 늘린다는 의미이다.
  • 각 컨테이너가 차지하는 비율을 조절하고 싶은 경우, 다음과 같이 할 수 있다.
    appContainer: {
      flex: 1,
    },
    inputContainer: {
      flex: 1,
    },
    goalsContainer: {
      flex: 3,
    },

6. 터치 시 Ripple

  • 안드로이드의 경우, android_ripple 속성을 추가하면 된다.
  • ripple 효과를 컨테이너 내부에 주고 싶어서 Pressable 컴포넌트를 View 안으로 위치를 수정하였다.
    <View style={styles.goalItem}>
      <Pressable android_ripple={{ color: "#dddddd" }} onPress={() => onDelteGoal(id)}>
        <Text style={styles.goalText}>{title}</Text>
      </Pressable>
    </View>
  • iOS의 경우, Pressable에 style 속성 안에 함수를 추가해야 한다.
  • pressed가 true인 경우에만 스타일을 적용한다.
    <View style={styles.goalItem}>
      <Pressable
        style={({ pressed }) => pressed && styles.pressed}
        android_ripple={{ color: "#210644" }}
        onPress={() => onDelteGoal(id)}
      >
        <Text style={styles.goalText}>{title}</Text>
      </Pressable>
    </View>


이벤트 처리

1. TextInput 이벤트

  • onChangeText 속성을 사용할 수 있다.
  • onChangeText는 입력된 값을 자동으로 받는다.

2. Button 이벤트

  • onPress 속성을 사용할 수 있다.

3. Pressable 컴포넌트 이벤트

  • RN에서는 특정 컴포넌트를 터치할 수 있게 하기 위해서는 Pressable 컴포넌트로 감싸야 한다.
  • onPress 속성을 사용할 수 있다.
    <Pressable onPress={() => {}}>
      <View style={styles.goalItem}>
        <Text style={styles.goalText}>{title}</Text>
      </View>
    </Pressable>


스크롤 구현

1. ScrollView 컴포넌트

  • RN에서 제공하는 기본 컴포넌트 중 하나이다.
  • 스크롤 가능 영역를 조절하기 위해서는 컨테이너인 View로 감싸야 한다. → 부모 컴포넌트가 스크롤 가능 영역을 조절하기 때문이다.
  • iOS의 스크롤 뷰의 기본 기능인 튀어오르기 효과는 alwaysBounceVertical 속성으로 ON/OFF 할 수 있다. → 스크롤 가능 영역을 넘지 않는 경우에만 적용된다.

2. FlatList 컴포넌트 ✨

  • 스크롤 뷰는 모든 자식 요소들을 렌더링하기 때문에, 보이지 않는 부분까지도 렌더링되고 있다.
  • 자식 요소들이 많아진다면, 성능의 문제가 발생할 수 있다.
  • 이럴 때 FlatList로 대체해서 사용할 수 있다. ⇒ FlatList는 보이는 부분만 렌더링한다.
  • FlatList는 map을 통해 데이터를 수동으로 매핑하지 않아도 된다.
  • 2가지 중요한 속성을 사용하면 된다.
    1. data: 목록으로 출력할 데이터

    2. renderItem: 자동으로 data의 개별 항목을 매개변수로 받는다. 렌더링 할 JSX 코드를 return 한다.

      매개변수인 개별 항목은 item에 실제 데이터 항목을 가지고 있고, index도 가진다.

  • alwaysBounceVertical 속성은 FlatList에도 똑같이 지원된다.
  • 이렇게 사용할 수 있다.
    • 열림/닫힘 태그를 사용하지 않는다.

      <View style={styles.goalsContainer}>
        <FlatList
          data={courseGoals}
          renderItem={(goal) => {
            return (
              <View style={styles.goalItem}>
                <Text style={styles.goalText}>{goal.item}</Text>
              </View>
            );
          }}
          alwaysBounceVertical={false}
        />
      </View>
  • FlatList에 key를 추가하는 2가지 방법이 있다.
    1. data에 key 프로퍼티를 가진 객체를 주는 방법

    2. data에 key 프로퍼티가 없는 경우, FlatList에 keyExtractor 속성을 추가하는 방법

      keyExtractor는 모든 항목에서 key를 가져오라고 호출하는 함수를 가진다.
      keyExtractor={(item, index) => {
        return item.id;
      }}


모달 구현

  • 모달로 만들고 싶은 부분을 Modal 컴포넌트로 감싸면 된다.
  • 모달의 Show/Hide는 state를 통해 관리해야 한다.
    {modalIsVisible && <GoalInput onAddGoal={addGoalHandler} />}
  • 하지만, 이런 방식을 사용하면 Modal 자체의 애니메이션이 존재하지 않는다.
  • 모달이 제공하는 기본 속성인 visibleanimationType을 사용하면 좀 더 퀄리티 있는 모달을 만들 수 있다.
    <Modal visible={modalIsVisible} animationType='slide'>
      <View style={styles.inputContainer}>
        ...
      </View>
    </Modal>

0개의 댓글