화면 위에 항상 떠있는 FAB를 만들어보도록 하겠습니다. 

 

www.youtube.com/watch?v=umCX1-Tq25k

* 아이콘 색 변경시 android가 아닌 app:tint="@android:color/white"를 쓰자

 

- to_bottom_anim.xml에서 scale(from,to)을 잡아주지 않으면 접힐때 아이콘 크기가 1로 다시 설정 됨

 

- 다이나믹하게 생성되는 버튼의 clickable을 설정 해주지 않으면 visibility가 false여도 클릭이 된다.

 

- BindingAdapter를 추가하여 isclick 변수에 따라 visibility와 clickable 설정하도록 했다.

 

Activity 등에 클래스 데이터를 전달하기위해 Serialization, Deserialization하는 코드로 화면 간 데이터는 최소화하여 전달하도록 권장하고 있으므로 그냥 방법만 알아두자

 

@Entity(tableName = "card_table")
data class Card(
        @PrimaryKey(autoGenerate = true) val id: Long?,
        @ColumnInfo(name = "card_name") val cardName: String?,
        @ColumnInfo(name = "card_number") val cardNumber: String?,
        @ColumnInfo(name = "limit_amount") val limitAmount: Long = 0,
        @ColumnInfo(name = "description") val description: String?
): Parcelable {
    constructor(name: String, number: String, limit: Long, desc: String): this(null, name, number, limit, desc)

    constructor(parcel: Parcel) : this(null, parcel.readString(), parcel.readString(), parcel.readLong(), parcel.readString())

    override fun describeContents(): Int {
        return 0
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(cardName)
        parcel.writeString(cardNumber)
        parcel.writeLong(limitAmount)
        parcel.writeString(description)
    }

    companion object CREATOR : Parcelable.Creator<Card> {
        override fun createFromParcel(parcel: Parcel): Card {
            return Card(parcel)
        }

        override fun newArray(size: Int): Array<Card?> {
            return arrayOfNulls(size)
        }
    }
}

 

위와 같이 boilerplate 코드와 override 함수들로인해 data class의 코드가 많이 복잡해지고 attribute의 non-null 속성도 보장하지 못하게 된다.

 

 

PanResponder API를 통해 사용자의 이벤트(스와이프, 탭, 핀치, 스크롤링 등)에 따라 앱 상태를 조작할 수 있습니다. 

 

요번에는 panresponder를 이용하여 사용자의 드래그 앤 드랍 이벤트를 처리할 수 있는 예제를 만들어 보겠습니다. 

 

panresponder.js 생성

1. 우선 여느 component와 같이 'react-native'에서 Dimensions, PanResponder을 import 합니다. 

 

2. Dimensions를 통해 화면의 너비, 높이 값을 가져옵니다. 
const { width, height } = Dimensions.get('window')

 

3. 사용자의 이벤트를 받기 전 view의 위치를 저장하는 oPosition 객체를 생성하고 화면의 중앙에 위치할 수 있도록 초기 값을 셋팅해줍니다. oPosition 객체는 사용자의 release 이벤트가 발생하면 해당 위치의 값으로 설정 됩니다.

* 이벤트 받을 객체(크기 200)의 왼쪽 윗 부분을 기준 점으로 지정

oPosition: {
        x: (width / 2) - 100,
        y: (height / 2) - 100,
      }

4. 사용자의 move 이벤트가 발생 시 현재 위치를 저장하는 position 객체를 생성하고 3과 같이 화면 중앙 값으로 초기 값을 저장합니다.

 

5. 내가 정의한 onPanResponderMove와 onPanResponderRelease 메서드를 PandResponder의 move, release 이벤트 함수로 사용할 수 있도록 정의하고 PanResponder.create에서 PandResponder의 이벤트 함수들과 사용자 정의 함수를 연결해줍니다.

* PanResponder를 생성 시 onStartShouldSetPanResponder에 true 값은 요소를 터치 할 때 지정한 move, release 함수가 활성화 됨을 의미 합니다.

 

6. _handlePanResponderMove (onPanResponderMove)의 로직을 만들어 줍니다.

객체가 사용자의 이동 이벤트를 받으면 evt와 gesture 파라미터를 받게 되는데 evt의 경우 객체내 터치 좌표, 연속된 이벤트의 배열 등 사용자 이벤트 자체 정보를 포함하는 반면 gesture의 경우 이벤트의 움직임과 관련 정보를 포함하고 있어 요번 예제에서는 gesture 정보를 사용합니다. 

move 이벤트의 원점 - 이동된 점으로 이동한 거리를 계산하고 

let ydiff = gestureState.y0 - gestureState.moveY 

position의 y 값을 이동전 y 값 - 이동 값을 통해 move 이벤트의 이동 위치로 저장합니다. 

y: this.state.oPosition.y - ydiff
   

7, _handlePanResponderRelease (onPanResponderRelease)에 release 이벤트가 발생 시 oPosition을 사용자가 객체를 드랍 했을 때의 위치로 저장하고 새로 이벤트를 받을 수 있도록 합니다. 

<View {...this._panResponder.panHandlers}
	style={[styles.box, { marginLeft: this.state.position.x, marginTop: this.state.position.y }
    ]} />

panResponder의 panHandlers를 지정하여 사용자 이벤트를 받을 수 있는 객체로 지정하고 객체의 왼쪽 위 좌표를 기준으로 margin 값을 주어 이벤트 대상 객체의 위치를 지정합니다.

 

빨간 박스의 View를 눌러 위치를 이동시키면 좌표 정보가 상단에 표시되고 마우스를 떼면 해당 위치에 박스가 위치하는 것을 볼 수 있음

 

이렇게 panresponder를 이용하여 사용자 이벤트를 재정의해서 등록하여 이벤트를 활성화 시키고 특정 view에 연결하는 방법을 알아 보았습니다. 

'React native' 카테고리의 다른 글

크로스 플렛폼 - NetInfo API  (0) 2020.01.19
크로스 플렛폼 - Geolocation  (0) 2020.01.19
크로스 플랫폼 - Clipboard API  (0) 2020.01.19
크로스 플랫폼 - AsyncStorage  (0) 2020.01.12
크로스 플랫폼 - AppState API  (0) 2020.01.12

NetInfo API를 이용하여 기기의 네트워크의 연결 유무를 알 수 있습니다. 

 

geolocation에서와 같이 안드로이드에는 권한을 추가해 줘야 합니다. 

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

 

netinfo를 위해 npm module을 설치하고 link를 해줍니다.

npm install --save @react-native-community/netinfo

react-native link @react-native-community/netinfo

*iOS emulator의 경우 ios폴더 내에 pod install로 module을 설치해주자

 

1. netinfo.js를 생성하고 'react-native-community'에서 NetInfo import한다.

생성자에 connectionInfo: {}를 통해 연결 정보 state를 생성한다.

 

2. NetInfo를 통해 초기 연결 상태를 파악하고 state에 저장

NetInfo.fetch().then(connectionInfo => {
       console.log("Connection type", connectionInfo.type)
       console.log("Is connected?", connectionInfo.isConnected)
       this.setState(connectionInfo)
     })

3. 실시간으로 연결 정보를 파악할 수 있도록 리스너를 추가하여 그 결과를 state에 저장

NetInfo.addEventListener(connectionInfo => {
       console.log("Changed Connection type", connectionInfo.type);
       console.log("Is connected?", connectionInfo.isConnected);
       this.setState(connectionInfo)
     });

4. render에서 연결 type을 통해 어떤 연결 모듈을 가지고 있는지 출력하도록 한다.

코드 실행 시 위와 같이 현재 기기의 연결 타입이 출력 됨

iOS의 경우 개발중인 데스크탑의 wifi를 해제하면 none으로 연결 정보가 업데이트 되는 것을 확인 할 수 있다.

'React native' 카테고리의 다른 글

크로스 플렛폼 - PanResponder  (0) 2020.01.26
크로스 플렛폼 - Geolocation  (0) 2020.01.19
크로스 플랫폼 - Clipboard API  (0) 2020.01.19
크로스 플랫폼 - AsyncStorage  (0) 2020.01.12
크로스 플랫폼 - AppState API  (0) 2020.01.12

기기의 위도, 경도를 알아내기 위한 API를 구현해보겠습니다.

 

아래 명령어로 geolocation module을 설치합니다. 

npm install @react-native-community/geolocation -save

 

*설치 후 geolocation module link와 pod install을 진행해야 한다고 에뮬레이터에 가이드가 나올 수 있다 시키는대로 진행하자

 

위치 정보를 이용하기 위한 권한이 iOS의 경우 기본으로 활성화되어 있으나 안드로이드의 경우 AndroidManifest.xml에 아래 권한 요청을 추가해 줘야 합니다. (추가 후 앱 재실행)

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

 

1. geolocation.js를 만들고 geolocation을 추가한다

import Geolocation from '@react-native-community/geolocation'

 

2. 현재위치 정보, 새로운 위치 정보, 위치 정보 watch id를(해제를 위해) 저장하는 state 정의

this.state = { 
            originalCoords: {},
            updatedCoords: {},
            id: ''
        }

3. 현재 위치 정보를 받아오는 로직을 componentDidMount에 정의

Geolocation.getCurrentPosition(
            (info) => {
                this.setState({
                    originalCoords: info.coords
                })
            },
            (err) => console.log('err : ', err)
        )

코드 실행 시 1회 현재 위치 정보를 얻어 state의 originalCoords에 저장, 에러 발생 시 로그 출력

 

4. 위치 정보가 갱신(기기가 이동) 할 때 마다 정보를 업데이트 하는 watch 정의

let id = Geolocation.watchPosition(
            (success) => {
                this.setState({
                    id,
                    updatedCoords: success.coords
                })
            },
            (err) => console.log('err : ', err)
        )

watch의 id를 저장해둬야 나중에 해제가 가능하다

 

5. watch를 해제하는 함수 추가

clearWatch(){
        Geolocation.clearWatch(this.state.id)
    }

4에서 저장한 state 의 id를 사용하여 watch를 해제해준다.

 

6. render에 시작 시 위치, 업데이트 되면서 바뀌는 위치 정보를 표시해주도록 정의한다.

 

실행 시(왼쪽) 초기 위치 정보가 출력되고 위치 이동 시(우측) 업데이트 된 위치 정보가 표시 됨

iOS emulator의 경우 Debug -> Location 메뉴를 통해 emulator의 위치 정보를 변경할 수 있고 변경 시 바로 앱의 위치 정보가 업데이트 됨을 확인 할 수 있다.

 

ClearWatch 버튼을 눌러 위치 정보 갱신을 중지하면 emulator의 위치 설정을 변경해도 더 이상 업데이트가 되지 않는 것을 확인 할 수 있다.

'React native' 카테고리의 다른 글

크로스 플렛폼 - PanResponder  (0) 2020.01.26
크로스 플렛폼 - NetInfo API  (0) 2020.01.19
크로스 플랫폼 - Clipboard API  (0) 2020.01.19
크로스 플랫폼 - AsyncStorage  (0) 2020.01.12
크로스 플랫폼 - AppState API  (0) 2020.01.12

요번 포스팅은 복사, 붙여넣기 기능을 구현해 보도록 하겠습니다. 

 

이 API는 getString(), setString() 두 함수로 간단히 구현할 수 있습니다. 

 

1. clipboard.js를 생성하고 react-native에서 Clipboard, getString component를 import 합니다. 

 

2. componentDidMount 오버라이드 함수에 Clipboard.setString('HelloWorld')으로 초기 clipboard 값을 설정합니다. 

 

3. updateClipboard (string) 함수에서 inputText에 입력이 발생할 때 마다 Clipboard.setString(string)을 이용하여 clipboard에 입력된 텍스트를 넣어둡니다. 

 

4. 지난 비동기 함수 동작 방식으로 async-await를 이용하여 pushClipboardToArray() 함수에서 clipboard에 저장된 텍스트를 component state인 clipboardData 배열에 push 하도록 합니다.

*this.pushClipboardToArray = this.pushClipboardToArray.bind(this)로 async 함수를 binding하여 사용하도록 합니다. 

 

이제 사용자 이벤트(텍스트 입력, 클립보드 내용 저장 버튼)를 위해 render를 구성합니다. 

 

TextInput에서 onChangeText 이벤트가 발생하면 3번의 updateClipboard 함수가 호출 될 수 있도록 익명 함수를 설정합니다.

 

TouchableHighlight를 누르면 binding 시켰던 4번의 pushClipboardToArray 함수를 호출 하도록 구현합니다. 

 

clipboardData.map((d, i) => {
                    return <Text key={i}>{d}</Text>
                })

render 하단에 clipboardData 배열의 map을 이용하여 저장된 데이터를 출력해주는 로직입니다. 

 

map을 이용하면 배열 아이템 하나하나에 대해 전달된 익명 함수를 실행하게 되는데 그 인자로 저장된 데이터 d와 인덱스 i가 전달되고 Text 문을 return하여 데이터를 화면에 출력하게 됩니다. 

 

실행 결과

코드를 실행해보면 위와 같이 바로 버튼을 누르면 초기 설정값인 'HelloWorld'가 출력되고 텍스트를 입력 후 버튼을 누를때 마다 입력한 결과가 목록으로 출력되는 걸 볼 수 있습니다. 

'React native' 카테고리의 다른 글

크로스 플렛폼 - NetInfo API  (0) 2020.01.19
크로스 플렛폼 - Geolocation  (0) 2020.01.19
크로스 플랫폼 - AsyncStorage  (0) 2020.01.12
크로스 플랫폼 - AppState API  (0) 2020.01.12
크로스 플랫폼 - Alert dialog  (0) 2020.01.10

앱의 데이터를 유지하고 저장하는 좋은 방법중 하나이며 비동기 방식입니다. 

 

아래와 같이 AsyncStorage를 설치해줍니다.

npm install --save @react-native-community/async-storage

(0.59부터 async-storage를 따로 추가해줘야함, 0.60 미만 에서는 react-native link를 통해 링크 작업따로 수행)

 

AsyncStorage는 보통 아래와 같은 경우에 많이 사용합니다. 

- 사용자 정보를 저장하여 매번 로그인이 필요없도록 할 때 등 사용자 정보 저장에 용이

- 대용량 데이터를 한번 받아 놓고 재사용

 

먼저 async-storeage에서 AsyncStorage를 import 합니다. 

 

임의의 person 객체를 생성하고 componentDidMount()에서 AsyncStorage.setItem(키, person을 json 형태의 문자열로 변환)을 통해 storage에 저장합니다. 

 

위 저장이 성공 시 then()으로 실패 시 catch()로 결과가 떨어집니다. 

 

반대로 AsyncStorage.getItem(key)를 통해 person 객체를 가져오는 함수 getPerson()를 정의합니다. 

 

then()내부에서 JSON.parse(res)를 통해 결과 문자열을 person 객체로 파싱하도록 합니다. 

 

Get President 버튼을 누르면 Storage에 저장된 결과를 보여준다.

 

AsyncStorage의 더 자세한 가이드는 아래 공식 사이트를 참고합니다. (merge의 사용법도 숙지합니다.)

https://facebook.github.io/react-native/docs/asyncstorage

 

그리고 아래와 같이 async, await 키워드를 통해 좀 더 자바 친숙(promise)한 비동기 storage로직을 구현하는 방법도 있습니다. 

async componentDidMount() {
	try{
    	await AsyncStorage.setItem(key, JSON.stringify(person)
        console.log('item stored')
    } catch (err) {
    	console.log('err: ', err)
    } 
}

 

안드로이드의 kotlin도 그렇고 대세는 좀 더 깔끔한 코드를 추구하는 람다방식이므로 예제의 코딩 방식을 익히도록 합시다

'React native' 카테고리의 다른 글

크로스 플렛폼 - Geolocation  (0) 2020.01.19
크로스 플랫폼 - Clipboard API  (0) 2020.01.19
크로스 플랫폼 - AppState API  (0) 2020.01.12
크로스 플랫폼 - Alert dialog  (0) 2020.01.10
Redux - 데이터 처리  (0) 2020.01.07

AppState API는 앱의 상태(active, inactive, background)를 이벤트 리스너를 통해 메서드 호출을 받습니다 

 

AppState의 사용 예

- 앱이 foreground로 변경되었을때 데이터의 갱신

- 주기적인 이벤트 발생시 background, foreground의 상태에 따라 동작 결정

- 앱이 foreground 상태가 됐을 때, 화면의 잠금 상태를  풀기 위해 인증 로직 동작

 

우선 react-native에서 AppState를 import합니다. 

 

componentDidMount() override함수에서 AppState.addEventListener(타입, 핸들러함수)를 통해 리스너를 등록합니다. 

 

handleAppStateChange 핸들러 함수를 정의하고 AppState가 변경될때 마다 log를 찍도록 합니다. 

 

앱 실행 후 iOS는 커맨드+쉬프트+h , 안드로이드는 Home 버튼을 눌러 홈화면으로 이동하면 개발자 도구의 console을 통해 아래와 같은 로그를 확인할 수 있습니다. 

개발자 도구 console.log

공식 가이드를 통해 더 자세한 내용과 예제를 확인해 봅니다.

https://facebook.github.io/react-native/docs/appstate

'React native' 카테고리의 다른 글

크로스 플랫폼 - Clipboard API  (0) 2020.01.19
크로스 플랫폼 - AsyncStorage  (0) 2020.01.12
크로스 플랫폼 - Alert dialog  (0) 2020.01.10
Redux - 데이터 처리  (0) 2020.01.07
Animation  (0) 2020.01.05

앱 개발을 하면서 가장 많이 쓰이는 기능 중 하나인 alert dialog를 띄워 봅니다.

 

Alert component를 react-native에서 import합니다. 

 

showMessage: false //Alert dialog의 유무를 확인하는 state를 정의

 

showAlert() 함수를 정의하여 Alert.alert로 dialog를 띄울 수 있도록 합니다. 

 

요번 예제에서는 Alert.alert(제목, 메세지, dialog button) 형식으로 기본적인 dialog 모양을 갖추도록 합니다. 

 

static alert(title, message?, buttons?, options? type?)

공식 가이드에 따르면 위와 같이 추가적인 옵션({cancelable:false})을 파라미터로 전달할 수 있습니다. 

 

코드에서 정의한 Show Message 버튼을 누르면 showMessage state를 true로 변경하여 render가 호출 되고 true인 경우 Showing message -success 텍스트가 나타나도록 합니다. 

 

iOS용 alert dialog와 android용 alert dialog

'React native' 카테고리의 다른 글

크로스 플랫폼 - AsyncStorage  (0) 2020.01.12
크로스 플랫폼 - AppState API  (0) 2020.01.12
Redux - 데이터 처리  (0) 2020.01.07
Animation  (0) 2020.01.05
Navigation  (0) 2020.01.02

앱을 개발 할 때 가장 중요한 부분중 하나가 일관성 있고 구조가 잘 잡힌 로컬 데이터 핸들링 입니다.

 

리덕스는 앱에 단 하나뿐인 전역 상태 객체로 앱 내 모든 Component에 props로 전달되고 데이터가 수정되면 변경된 데이터가 다시 전달됩니다.

 

리덕스는 store라는 곳에서 데이터를 관리하고 전역 state를 만들고 관리하는 context(react API)라는 기능을 이용합니다. 

 

리덕스 예제 구현

도서 목록을 관리하는 앱을 통해 리덕스를 구현해 보겠습니다. 

 

1. 리덕스 관련 의존성 라이브러리 설치

npm install --save redux react-redux

*설치 이후에 에뮬레이터 캐쉬를 비워줘야 하는건지 빌드, 실행이 잘 되지 않았네요..

 

2. actions.js, Books.js 파일을 생성하고 reducers 폴더와 그 아래 bookReducer.js, index.js를 생성합니다. 

* 리듀서는 객체를 반환하는 함수로 여러 리듀서들을 묶어 전역 state를 만들게 됩니다.

 

3. bookReducer.js에 책 객체를 정의하고 state를 반환하는 함수 생성

4. index.js에 루트 리듀서 생성(전역 state생성)

- redex에서 combineReducers import

- bookReducer를 import하여 combineReducers를 통해 루트 리듀서 생성

 

5. App.js에 리덕스 스토어를 만들고 provider를 통해 자식 Component에서 스토어를 참조할 수 있게 함

- Provider를 react-redux import하여 가져오기

- createStore를 redux import하여 가져오기

- rootReducer(reducers/index.js)를 이용하여 store 객체 생성 

- <Provider store={store}>로 감싼 자식 Component에 store를 전달

 

6. Books.js

* connect 함수를 이용해서 자식 component에서 데이터 참조, 커링함수 : 다른 함수를 반환하는 함수

- connect를 react-redux에서 import

- const {books} = this.props으로 books 데이터를 사용

const mapStateToProps = (state) => ({
  books: state.bookReducer.books
})
export default connect(mapStateToProps)(Books)

books 배열을 리덕스의 전역 state에서 꺼내 객체를 반환하고 connect 함수의 결과를 외부에 export

 

 7. 책을 추가할 수 있도록 actions.js에 액션 추가하기

- export const ADD_BOOK = 'ADD_BOOK' //리듀서에서 재사용할 수 있도록 상수 export

- addBook이라는 함수를 만들고 type과 추가할 book 객체를 반환

 

8. bookReducer에서 addBook 액션을 이용할 수 있게 만듦

- actions에서 ADD_BOOK을 import

- bookReducer의 두번째 인자로 action을 추가

- actions.type으로 분기하여 books state를 업데이트 할 수 있도록 로직 추가

* ...state.books는 스프레드 연산자로 기존 배열에 추가할 action.book을 더해서 books 배열을 만듦

 

9. Books.js에 사용자 이벤트를 통해 정의한 액션이 실행 되도록 처리

- actions에서 addBook, react-redux에서 connect를 import

- name과 author필드를 포함하는 initialState 생성

- updateInput 함수 추가

updateInput = (key, value) => {
    this.setState({
      ...this.state,
      [key]: value
    })
  }

* 텍스트가 입력 될 때 마다 불리며 현재 상태(...this.state)에 새로 업데이트 된 key:value로 업데이트 하여 state를 갱신한다고 이해하면 됨

 

- addBook 함수를 정의, connect를 통해 this.props.dispatchAddBook(this.state)를 호출 할 수 있도록 함

- 위에서 사용할 dispatchAddBook(actions.js의 addBook을 사용)을 connect로 연결하기 위해 아래와 같이 정의

const mapDispatchToProps = {
  dispatchAddBook: (book) => addBook(book)
}

- export default connect(mapStateToProps, mapDispatchToProps)(Books) 

* addBook action을 사용할 수 있도록 mapDispatchToProps를 connect에 전달

 

리덕스를 통해 데이터 레이어를 분리하고 자식 컴퍼넌트에서 데이터와 액션을 사용할 수 있도록 하는 과정은 아래와 같습니다. 

1. 리듀서를 생성하여 사용할 데이터를 정의

2. App.js에 1의 root reducer를 통해 store를 생성, <Provider> 로 store를 하위 component (Books.js)에 전달

3. 하위 component (Books.js)에서 connect를 통해 store를 참조(this.props을 통해 리듀서의 데이터와 함수를 참조 할 수 있다.)

4. actions.js에 리덕스 데이터를 이용한 비지니스 로직인 액션 추가

5. 리듀서에서 4에서 정의한 액션을 통해 데이터가 업데이트 될 수 있도록 정의

6. Component (Books.js)에서 사용자 이벤트를 받아 4에서 정의한 액션이 호출 될 수 있도록 connect를 사용

 

실행결과 : 내용을 입력하고 +를 누르면 목록에 추가 됨

 

더해서 추가된 책을 삭제하는 액션을 추가해 보겠습니다. 

 

10. bookReducer.js에 삭제를 위한 로직 추가

* npm i uuid -save 를 통해 id 발급(uuidV4) 모듈 추가 

- uuid/v4에서 uuidV4 import

- books 객체에 id : uuidV4() 로 아이디 필드 추가

- REMOVE_BOOK 케이스 처리를 위한 코드 추가

case REMOVE_BOOK:
            const index = state.books.findIndex(book => book.id === action.book.id)
            return {
                books: [...state.books.slice(0, index), ...state.books.slice(index+1)]
            }

books 목록에서 action을 통해 넘어온 id로 책의 index를 찾고 index에 해당하는 book만 빼고 앞뒤로 잘라 붙여 새로운 books를 리턴

 

11. actions.js에 uuid, 삭제 로직 추가

- REMOVE_BOOK export, uuid/v4 import

- ADD_BOOK의 book에 id: uuidV4()로 id 필드 추가

- addBook과 비슷하게 removeBook 정의

 

12. Books.js에 removeBook을 호출 하도록 추가

* 전반적으로 addBook과 비슷한 순서로 진행된다. 처음 addBook을 추가할 때 이해를 잘 해두면 두번은 쉽다?

- removeBook 함수를 추가하고 Remove 텍스트를 눌렀을때 선택된 book객체가 전달될 수 있도록 render에 아래 내용 추가

books.map((book, index) => (
              <View style={styles.book} key={index}>
                <Text style={styles.name}>{book.name}</Text>
                <Text style={styles.author}>{book.author}</Text>
                <Text onPress={() => this.removeBook(book)}>Remove</Text>
              </View>
            ))

- mapDispatchToProps에 dispatchRemoveBook 키로 removeBook 액션이 실행 되도록 connect

 

책 목록의 Remove를 누르면 삭제 된다.

 

지금까지 리덕스를 통해 데이터 정의, 비지니스 로직, 뷰 컴퍼넌트를 따로 개발할 수 있도록 레이어 분리하는 과정을 실습해 보았습니다.

 

MVVM 처럼 모델(데이터), 뷰, 비지니스 로직을 분리하는 방식의 아키텍처에 대한 이해가 없다면 왜 이렇게 복잡하게 개발을 해야 하는지 이해하기 힘들 수도 있습니다. 

 

어쨌든 학교에서 실습하듯이 모델, 뷰, 비지니스 로직을 한코드에 때려넣으면 프로젝트의 규모가 커짐에 따라, 개발 팀원들이 모듈을 나눠 개발 하는데 있어 엄청난 부담이 될 수 있습니다. 

 

참고하셔서 요번 포스팅의 실습 내용은 그 구조와 개발 방식을 꼭 이해하고 넘어가시길 바랍니다. 

'React native' 카테고리의 다른 글

크로스 플랫폼 - AppState API  (0) 2020.01.12
크로스 플랫폼 - Alert dialog  (0) 2020.01.10
Animation  (0) 2020.01.05
Navigation  (0) 2020.01.02
고급 Style  (0) 2019.12.29

+ Recent posts