Как использовать callback-и из js в kotlin в react-native которых можно вызвать много раз?

В React Native, если вы хотите вызывать Kotlin функцию много раз из JavaScript, то наилучшим способом является использование callback-ов с помощью Native Modules.

Для начала, вам нужно создать класс Kotlin, который будет являться модулем. Для этого вы должны создать новый файл с расширением .kt и объявить свой класс внутри него. Например, назовем его MyModule.

// MyModule.kt

package com.yourappname.modules

import com.facebook.react.bridge.*

class MyModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

}

В этом классе вы должны определить методы, которые вы хотите вызвать из JavaScript. Давайте создадим метод myMethod, который будет принимать один аргумент и вызывать callback.

// MyModule.kt

package com.yourappname.modules

import com.facebook.react.bridge.*
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter

class MyModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

    override fun getName(): String {
        return "MyModule"
    }

    // This method will be called from JavaScript
    @ReactMethod
    fun myMethod(argument: String, callback: Callback) {
        // Do something with the argument
        val result = "Hello, $argument!"

        // Invoke the callback with the result
        callback.invoke(result)
    }
}

Затем, вы должны зарегистрировать этот модуль в списке модулей вашего приложения. Для этого откройте файл MainApplication.kt и добавьте экземпляр этого модуля в открытый метод getPackages:

// MainApplication.kt

package com.yourappname

import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager
import com.yourappname.modules.MyModule // Import the module

class MainApplication : Application(), ReactApplication {

  private val reactNativeHost: ReactNativeHost = object : ReactNativeHost(this) {
      override fun getPackages(): List<ReactPackage> {
          val packages = PackageList(this).packages
          packages.add(MyModulePackage()) // Add the module package
          return packages
      }
  }

  override fun getReactNativeHost(): ReactNativeHost {
      return reactNativeHost
  }

  // ...
}

Затем, вы должны создать пакет для модуля, чтобы его можно было зарегистрировать в вашей конфигурации приложения. Создайте новый файл MyModulePackage.kt и добавьте в него следующий код:

// MyModulePackage.kt

package com.yourappname.modules

import com.facebook.react.ReactApplication
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager

class MyModulePackage : ReactPackage {
    override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
        val modules = mutableListOf<NativeModule>()
        modules.add(MyModule(reactContext)) // Add the module
        return modules
    }

    override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
        return emptyList()
    }
}

Теперь, когда вы настроили модуль, вы можете импортировать его в JavaScript и использовать его на вашем экране.

Для этого импортируйте NativeModules и вызовите ваш метод myMethod следующим образом:

import { NativeModules } from 'react-native';

// Call myMethod with an argument and a callback
NativeModules.MyModule.myMethod('World', (result) => {
  console.log(result); // Output: Hello, World!
});

Обратите внимание, что имя модуля MyModule соответствует имени, которое вы вернули в методе getName вашего модуля Kotlin.

Таким образом, вы можете использовать callback-и из JavaScript в Kotlin в React Native и вызывать их много раз. Это позволяет вам взаимодействовать с функциями и кодом на языке Kotlin и получать результаты обратно в JavaScript.