[ReactNative] Counter Native Module 만들어보기 - Kotlin편

han·2024년 1월 12일

ReactNative

목록 보기
6/8

Swift로 구현하기에 이어 Kotlin으로 안드로이드 기능도 추가해보자.

Counter 클래스 작성

일단 안드로이드 스튜디오를 사용해 프로젝트를 열어주고
app/src/com/{프로젝트명} 경로에 코틀린 클래스를 추가해주자.
나는 파일명을 CounterModule로 만들어주었다.

그리고 아래와 같이 작성해주었다.
리액트 네이티브에서 호출하기 위해서 Swift로 구현할때와 같은 모듈 이름과
메소드 이름으로 작성해주도록 하자.

// CounterModule.kt

package com.awesomeproject

import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.modules.core.DeviceEventManagerModule


class Counter(reactContext: ReactApplicationContext?) :
    ReactContextBaseJavaModule(reactContext) {
    private var count = 0

    override fun getName() = "Counter"
    
    // Swift 에서 constantsToExport 메소드와 같은 역할을 한다.
    override fun getConstants(): Map<String, Any>? {
        val constants: MutableMap<String, Any> = HashMap()
        constants.put("initialCount", 0)
        return constants
    }

    @ReactMethod
    fun increment() {
        count++
        emitCount()
    }

    @ReactMethod
    fun decrement() {
        count--
        emitCount()
    }

    private fun emitCount() {
        reactApplicationContext
            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
            .emit("onCountChanged", count)
    }
}

패키지 클래스 작성

공식문서에 따라, 패키지 클래스를 작성해주자.
다시 같은 경로에 CounterPackage라는 코틀린 클래스를 만들어주고
createNativeModules에 카운터 클래스를 추가해주자.

package com.awesomeprojectname

import android.view.View
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ReactShadowNode
import com.facebook.react.uimanager.ViewManager

class CounterPackage : ReactPackage {

    override fun createViewManagers(
        reactContext: ReactApplicationContext
    ): MutableList<ViewManager<View, ReactShadowNode<*>>> = mutableListOf()

    override fun createNativeModules(
        reactContext: ReactApplicationContext
    ): MutableList<NativeModule> = listOf(Counter(reactContext)).toMutableList()
}

MainApplication에 패키지 추가

reactNativeHost 값에서 작성한 카운터 패키지를 추가해주자.


class MainApplication : Application(), ReactApplication {

  ...

  override val reactNativeHost: ReactNativeHost =
      object : DefaultReactNativeHost(this) {
        override fun getPackages(): List<ReactPackage> =
            PackageList(this).packages.apply {
                add(CounterPackage()) // CounterPackage 추가
            }
      }
      
  ...

리액트 네이티브에서 사용하기

사실 Swift로 구현했을 때와 같은 스펙을 가지고있기 때문에 js쪽 코드는 변경할 게 없다.
이렇게 Swift & Kotlin을 사용해 두 플랫폼에서 카운터를 구현하는 간단한 예제 작성이 완료되었다.

const CounterModule = NativeModules.Counter;

const LagacyNativeCounter: React.FC = () => {
    const [ count, setCount ] = useState<number>(CounterModule.initialCount);
    
    useEffect(() => {
        const eventEmitter = new NativeEventEmitter(CounterModule);
        eventEmitter.addListener('onCountChanged', setCount);

        return () => {
            eventEmitter.removeAllListeners('onCountChanged');
        };
    }, []);

    return (
        <View style={styles.layout}>
            <Text style={styles.count}>{count}</Text>
            <Button title='INCREMENT' onPress={() => CounterModule.increment()} />
            <Button title='DECREMENT' onPress={() => CounterModule.decrement()} />
        </View>
    );
};
profile
크로스 플랫폼과 사랑에 빠진 개발자의 글 연습

0개의 댓글