728x90

리액트 네이티브를 공부하면서 네이티브모듈을 사용해보고 싶어졌다.

사용하기 위해서 코틀린 설정을 해봐야하는데 너무 오래걸렸다. 기록기록

네이티브 모듈을 사용하려면 모듈 생성 -> 패키지 등록 순으로 이루어진다.

먼저 react native 사이트에 있는 setting 방법으로 react-native cli 를 이용해서 프로젝트를 생성해 준다. 

안드로이드 스튜디오와 xcode 등 설벙은 공식 사이트를 참고했다.

https://reactnative.dev/docs/environment-setup

실행 환경은

MacOS m1

jdk 11

react-native 0.71 을 사용했다.

npx react-native init <프로젝트명>

으로 프로젝트를 생성해 준다.

 

 

 

1. android/build.gradle

먼저 생성된 프로젝트에서 android 디렉토리에 있는 build.gradle에 몇가지를 추가해준다.

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {
        buildToolsVersion = "33.0.0"
        minSdkVersion = 21
        compileSdkVersion = 33
        targetSdkVersion = 33
        kotlinVersion = "1.7.0"
        // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
        ndkVersion = "23.1.7779620"
    }
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:7.3.1")
        classpath("com.facebook.react:react-native-gradle-plugin")
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
    }
}

kotlinVersion을 1.7.0으로 해주고, dependencies에 classpath를 추가해준다.

 

2. android/app/build.gradle

다음으로는 adroid 안에 있는 app 안에 build.gradle 에 몇가지를 추가해준다.

apply plugin: "kotlin-android"
dependencies {
	implementation "org.jetbrains.kotlin:kotlin-stdlib"
   }

2 코드를 각각 추가해 줬다.

 

3. module 생성

main/java/com/exam 디렉토리에 calculator 디렉토리를 만들고 CalculatorModule.kt파일을 추가해 줬다.

package com.exam.calculator
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Callback

class CalculatorModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

    override fun getName():String="CalculatorModule"

    @ReactMethod
    fun add(a:Double,b:Double,callback:Callback){
        var c:Double = a+b
        callback.invoke(c)
    }
}

reactContext를  생성자 인자값으로 받고,ReactContextBaseJavaModul을 상속받는 CalculatorModule class를 만들어 줬다.  getName() 메소드를 override 했다. getName은 react-native js 단에서 사용할 모듈 이름이다. 클래스 이름과 같이 지어줬다.

@ReactMethod 어노테이션을 달아주면, react-native 단에서 함수로 불러 사용할 수 있다.

 

add 메소드를 만들고 , Double 타입의 인자 a,b와 Callback 을 받아 준다.

a+b의 값을 가지는 c 변수를 callback의 invoke 메소드에 넣어준다.

 

만들어 둔 module을 react-native에서 사용하기 위해서는 다음으로 Package 묶어서 보내줘야한다고한다.

package com.exam.calculator

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 CalculatorPackage : ReactPackage {

    override fun createViewManagers(
        reactContext: ReactApplicationContext
    ): List<ViewManager<*,*>> = emptyList()

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

CalculatorPackage class 를 ReactPackage를 상속받아 만들어 주고 createViewManagers 와 createNativeModules를 override해서 정의 해준다. 만든 모듈은 createNativeModules에 들어 간다.

마지막으로 MainApplication.java 에서 패키지로 등록해준다.

package com.exam;

import android.app.Application;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.soloader.SoLoader;
import java.util.List;
import com.exam.calculator.CalculatorPackage;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost =
      new DefaultReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
          return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          // Packages that cannot be autolinked yet can be added manually here, for example:
          // packages.add(new MyReactNativePackage());
          packages.add(new CalculatorPackage());
          return packages;
        }

        @Override
        protected String getJSMainModuleName() {
          return "index";
        }

        @Override
        protected boolean isNewArchEnabled() {
          return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
        }

        @Override
        protected Boolean isHermesEnabled() {
          return BuildConfig.IS_HERMES_ENABLED;
        }
      };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
    if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
      // If you opted-in for the New Architecture, we load the native entry point for this app.
      DefaultNewArchitectureEntryPoint.load();
    }
    ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
  }
}

CalculatorPackage를 import 해주고 getPackages() 메소드안에 Package.add() 의 인자 값으로 new 로 생성해 넘겨준다.

 

이렇게 만들어진 모듈을 react-native에서 NativeModules를 먼저 import한뒤 NativeModules.모듈 로 사용할수 있다 .이때 모듈은 getName() 에서 정의해준 모듈 이름으로 사용가능하다. 

import {NativeModules} from 'react-native';
const {CalculatorModule} = NativeModules;
  CalculatorModule.add(1, 2, (sum: number) => {
    console.log(sum);
  });

그렇게 심도있게 알지는 못했지만 어쨌든 원하는 결과 값이 나온것에 우선 만족한다.

728x90
728x90
import 'package:flutter/material.dart';

void main() {
  return runApp(MaterialApp(
      title: "Hello World",
      home: Scaffold(
          appBar: AppBar(title: Text('Widget')),
          body: _FirstStatefulWidget())));
}

class _FirstStatefulWidget extends StatefulWidget {
  @override
  State createState() => _FirstStatefulWidgetState();
}

class _FirstStatefulWidgetState extends State<_FirstStatefulWidget> {
  @override
  Widget build(BuildContext context) {
    return Text("statefule widget");
  }
}

stateless 와 다르게 build() 메서드가 없다.

 

statefulWidget을 상속받는 위젯 class -> createState ->

위 클래스를 타입으로하는 State를 상속받는 클래스 -> build 메소드

 

statefulWidget 은 상태를 가진다.

변동부 + 고정부

변동부 =_FirstStatefulWidgetState

고정부 =_FirstStatefulWidget

 

728x90
728x90

연습 겸 코드 기록으로 작성

데이터베이스는 docker 를 이용해 mariadb 컨테이너를 사용하고, 서버로는 springboot , 프론트로는 react를 사용해보기로 했다.

 

1. mariadb - docker

먼저 docker-desktop 이나 docker가 설치 되어있다는 가정하에 진행한다.

먼저 mariadb 이미지를 pull 받아준다.

docker pull mariadb

docker run으로 mariadb 컨테이너를 만들어 줍니다.

docker run -dit --name=mariadb -p 3307:3306 -e MARIADB_ROOT_PASSWORD=root --restart=always mariadb

docker exec 로 root 접속해 유저생성, 데이터베이스 생성, 권한을 부여해 줍니다.

docker exec -it mariadb mysql -u root -p
password: root
CREATE USER 'hiio'@'%' identified by 'hiio';
CREATE DATABASE HIIO;
GRANT ALL PRIVILEGES ON HIIO.* TO 'hiio'@'%';

connect 연결테스트를 해보기 위해서 dbeaver로 접속해 봅니다.

 

 

2. spring boot

VScode를 사용합니다.

JDK 는 11버전을 사용합니다.

 

vscode에 java 와 spring boot Extention을 설치 해주고 F1을 눌러 spring boot initialize 를 gradle로 만들어 줍니다.

버전은 2.7.8 를 사용해 줬습니다.

 

언어는 JAVA로 선택하고, 패키지 명을 정해줍니다.

패키지 타입은 JAR로 선택해 줬습니다.

 

JAVA 버전은 11로 선택해 주고 

초기 Dependency 는 Lombok , Devtools, web 을선택해 줬습니다.

디렉토리를 선택해면 그 하위에 파일들이 생기게 됩니다.

 

 

PracApplication 을 실행해 봅니다.

 

잘 실행이 되네요.

 

3. create-react-app

node 를 설치한 상태에서 npx를 사용해 create-react-app 으로 리액트를 설치해 줍니다.

 

설치가 완료되고 나서 front 디렉토리로 이동후에 npm run start 명렁어로 실행해 봅니다.

 

완료! 

 

728x90

+ Recent posts