Как импортировать модуль узла в React-Kotlin?
Я создал приложение с помощью команды create-реагировать-kotlin-app, и он прекрасно загружается в Chrome. Я добавил пакет React Material UI через NPM, и это было успешно. Теперь, как мне использовать модуль Material UI в моем компоненте?
Обычно с JavaScript это просто import Button from '@material-ui/core/Button'
в верхней части файла компонента, но Kotlin это не нравится.
Как мне перевести эту строку на Kotlin? Я не использую Gradle.
2 ответа
Я боролся с этой проблемой уже несколько дней. Я придумал следующее решение. Сначала мы увидим несколько способов объявления внешних модулей, затем я покажу, как их использовать.
Рассмотрим следующий код JavaScript
import Button from '@material-ui/core/Button' // this means button is exported as default
Это будет импортировано в kotlin следующими способами
Button.kt
@file:JsModule('@material-ui/core/Button')
@file:JsNonModule
package com.mypckage.mykillerapp
import react.Component
import react.RProps
import react.RState
import react.ReactElement
// way 1
@JsName("default") // because it was exported as default
external val Button : RClass<RProps>
// way 2
@JsName("default")
external class Button : Component<RProps,RState> {
override fun render(): ReactElement?
}
Но опять же, если оператор, предназначенный для kotlin, должен соответствовать приведенному ниже оператору импорта javascript,
import { Button } from "material-ui" // not exported as default
Мы используем следующий подход: Button.kt
@file:JsModule('@material-ui/core/Button')
@file:JsNonModule
package com.mypckage.mykillerapp
import react.Component
import react.RProps
import react.RState
import react.ReactElement
// way 1
@JsName("Button") // because it was exported as default
external val Button : RClass<RProps>
// way 2
@JsName("Button")
external class Button : Component<RProps,RState> {
override fun render(): ReactElement?
}
Как только вы заявили о том, как использовать ваши компоненты, вы можете просто использовать их следующим образом:
//way 1:
fun RBuilder.render() {
div {
Button {
attrs.asDynamic.className="submit-button"
+"Submit"
}
}
}
//way 2:
fun RBuilder.render() {
div {
child(Button::class) {
attrs.asDynamic.className="submit-button"
+"Submit"
}
}
}
отличный. Вы импортировали свой компонент. Но до тех пор вы не полагаетесь на безопасность типа kotlin и даже на завершение кода, чтобы достичь этого, вы должны пойти на дополнительную длину
как показано ниже
external interface ButtonProps: RProps {
var className : String
var onClick: (Event?)->Unit
var color: String
// . . .
var href: String
}
затем идти вперед и объявить вашу кнопку как
@JsModule("@material-ui/core/Button")
@JsNonModule
@JsName("default") // because it was exported as default
external val Button : RClass<ButtonProps>
и теперь вы можете использовать его с типом безопасности и завершения кода, как показано ниже
fun RBuilder.render() {
div {
Button {
attrs {
className = "submit-button"
onClick = {
window.alert("Vois La")
}
}
+"Submit"
}
}
}
Надеюсь это поможет. Удачного кодирования
Способ импорта зависимостей Kotlin близок к стандартному импорту JS:
import React from 'react';
export function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
Основано на создании простого компонента React с Kotlin.
package hello
import react.*
import react.dom.*
fun RBuilder.hello(name: String) {
h1 {
+"Hello, $name"
}
}
Обычно (поскольку Kotlin основан на Java), он использует инструмент Gradle для обработки зависимостей:
// part of build.gradle
kotlinFrontend {
// ...
npm {
// ...
dependency("react")
dependency("react-dom")
dependency("react-router")
dependency("react-markdown")
devDependency("css-loader")
devDependency("babel-core")
// ...
}
И ссылки, как указано выше:
HomeView.kt:
// https://github.com/Kotlin/kotlin-fullstack-sample/blob/master/frontend/src/org/jetbrains/demo/thinkter/HomeView.kt
import kotlinx.html.*
import org.jetbrains.demo.thinkter.model.*
import react.*
import react.dom.*
import kotlinx.coroutines.experimental.launch
ReactMarkdown.kt:
// https://github.com/Kotlin/kotlin-fullstack-sample/blob/master/frontend/src/org/jetbrains/demo/thinkter/ReactMarkdown.kt
package org.jetbrains.demo.thinkter
import react.*
private val ReactMarkdown: dynamic = runtime.wrappers.require("react-markdown")
Основано на: https://github.com/Kotlin/kotlin-fullstack-sample
В create-react-kotlin-app
дополнительно столкнулся с возможностью импорта с @JsModule()
аннотации, а управление зависимостями обрабатывается стандартным способом через package.json
:
// src/logo/Logo.kt (outcome of creating new app)
package logo
import react.*
import react.dom.*
import kotlinext.js.*
import kotlinx.html.style
@JsModule("src/logo/react.svg")
external val reactLogo: dynamic
@JsModule("src/logo/kotlin.svg")
external val kotlinLogo: dynamic
И может также успешно использоваться для импорта библиотек JS.
Другой способ будет использовать kotlinext.js.*
:
// index/index.kt
import kotlinext.js.*
fun main(args: Array<String>) {
requireAll(require.context("src", true, js("/\\.css$/")))
// ...
}
Что также обеспечивает require(module: String)
функция.