[Ktjs x React] 踩坑,实现 Router

先前写过一篇用 Kotlin 开发 React 应用的文章(点击阅读),在该篇内讲述了最基础的使用开发方法,在实际开发中,只有这样肯定是不行的,多页面的应用也很常见。而在 React 下,要实现多页面的程序,就需要使用 Router。

首先我们按之前的文章新建项目,并且加上 gradle 管理,由于 npm 和 gradle 是两套完全不同的依赖体系,因此我们有必要先将它们联系起来,JetBrains 官方已经为 React 开发了各种 wrapper,引入使用即可:

implementation 'org.jetbrains:kotlin-react:16.6.0-pre.71-kotlin-1.3.31'
implementation 'org.jetbrains:kotlin-redux:4.0.0-pre.72-kotlin-1.3.31'
implementation 'org.jetbrains:kotlin-extensions:1.0.1-pre.71-kotlin-1.3.31'
implementation 'org.jetbrains:kotlin-react-dom:16.6.0-pre.71-kotlin-1.3.31'
implementation 'org.jetbrains:kotlin-react-redux:5.0.7-pre.71-kotlin-1.3.31'
implementation 'org.jetbrains:kotlin-react-router-dom:4.3.1-pre.72-kotlin-1.3.31'

这个操作将会把 kotlin 所需要的 kjsm 文件引入,从而在 IDE 内可以实现代码提示,重构等功能。如果你对 React 已经很熟练,熟到可以完全无提示编写代码的程度,也可以不做这一步。

然后改一下 package.json,将 router 加入:

"dependencies": {
    "@jetbrains/kotlin-react-router-dom": "^4.3.1-pre.72",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-router-dom": "^5.0.1",
    "react-router": "^5.0.1"
},

需要注意的是,@jetbrains/kotlin-react-router-dom 这个包的版本,尽量和 gradle 脚本内的版本保持一致(当然不一致也能正常运行,但是编译时会有警告)。

执行 npm installyarn install 来安装依赖,完成后就可以在 IntelliJ 中顺畅的开发了。


下面就来改造一下代码,官方的工程向导会为我们创建一个 index.kt,它的内容如下:

fun main(args: Array) {
    requireAll(require.context("src", true, js("/\\.css$/")))
    render(document.getElementById("root")) {
        app()
    }
}

此处的 app() 是扩展于 RBuilder 的函数,它返回一个 ReactElement,即 react 将渲染这个组件。

我们的需求是按 router 来跳转至不同的页面,所以进行以下改造:

fun RBuilder.route() = browserRouter {
    switch {
        route("/", exact = true) { app() }
        route("/page", exact = true) { page() }
        // default
        redirect(from = "*", to = "/")
    }
}

fun main(args: Array) {
    requireAll(require.context("src", true, js("/\\.css$/")))
    render(document.getElementById("root")) {
        route()
    }
}

这里的 page() 是另一个与 app() 几乎完全一致的东西,它也是一个 React 组件。

这样我们就可以在 app 里,写一些代码来令页面跳转到 page:

button(classes = "btn") {
    +"Jump!"
    attrs {
        onClickFunction = {
            window.location.pathname = "/page"
        }
    }
}

如果要在跳转时带上参数,也可以参考 router 的文档(点击查阅),此处就不赘述了。


另外还有一些小问题,比如说 input 的内容改变事件,在 js 里写起来比较简单,可以直接 e.target.value,而在 kotlin 下,则需要进行一步类型转换:

input(classes = "input-search") {
    attrs {
        placeholder = "输入要搜索的关键字"
        onChangeFunction = {
            keyword = (it.target as HTMLInputElement).value
        }
    }
}

你可能感兴趣的:([Ktjs x React] 踩坑,实现 Router)