Slide 1

Slide 1 text

ReactでToDoアプリを 作ってみた Osaka Mix Leap Study #23 React Native勉強会

Slide 2

Slide 2 text

アジェンダ 1. 自己紹介 2. 作るアプリの仕様 3. ReactでToDoアプリを作る 4. Reduxを導入してみる 5. まとめ

Slide 3

Slide 3 text

自己紹介 ヤマサキ ヨシヒロ 山崎 好洋 ヤフー18年度 新卒 ● Vue.js ● DDD ● TDD ● モブプロ ● Kotlin @44x1carbon

Slide 4

Slide 4 text

Vue.jsしか触ってこなかったから Reactを触ってみよう!!

Slide 5

Slide 5 text

React(Kotlin)でToDoアプリを 作ってみた

Slide 6

Slide 6 text

KotlinでReactとは? 最近、Androidやサーバーサイドで注目されている、JetBrains社製のJVM言語のKotlin Javaバイトコード以外にもJavaScript(Kotlin/JS)やバイナリコード(Kotlin/Native)にも変 換ができる。 ReactをKotlin/JS用にラップしたライブラリ kotlin-reactがJetBrainsから提供されている

Slide 7

Slide 7 text

作るアプリの仕様 【React】ToDoアプリを作ってみよう @mikan3rd ● ToDo一覧表示 ● ToDoの投稿 ● ToDoの完了/未完了切り替え

Slide 8

Slide 8 text

コマンドでプロジェクトの雛形を作成 1. コマンドのインストール npm install -g create-react-kotlin-app 2. プロジェクトの作成 create-react-kotlin-app todo-list ※実行前にJDK8をインストールしておく必要があります。

Slide 9

Slide 9 text

プロジェクトのディレクトリ構造

Slide 10

Slide 10 text

実行は npm start

Slide 11

Slide 11 text

設定を書き換えたい場合は npm run eject

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Kotlinの言語仕様紹介(少しだけ)

Slide 14

Slide 14 text

コンストラクタ プライマリコンストラクタはクラスヘッダ部分に書きます class Person constructor(val firstName: String) { ... } アノテーションやアクセス修飾子がない場合はconstructorキーワードを省略できます class Person(val firstName: String) { ... }

Slide 15

Slide 15 text

拡張メソッド 既存の型にメソッドを追加することができます。 fun 拡張したい型.拡張メソッド名 例) fun String.toNewLine() = this + “\n” “Hoge”.toNewLine()

Slide 16

Slide 16 text

引数の最後にラムダを渡す時の省略記法 fun hoge(s: String, func: (String) -> Unit) 引数の最後のラムダは括弧の外側に書くことができます。 hoge(“Hoge”, { s -> println(s) }) hoge(“Hoge”) { s -> println(s) } 引数がラムダだけの場合、丸括弧を省略することができます。 fun fuga(func: (String) -> Unit) fuga { s -> println(s) }

Slide 17

Slide 17 text

kotlin-reactでどう書く? 1. Rendering 2. List Rendering 3. State 4. Props 5. Handling Event

Slide 18

Slide 18 text

Rendering

Slide 19

Slide 19 text

main(JavaScript) import './css/index.css' import React from 'react' import ReactDOM from 'react-dom' import App from './App' ReactDOM.render(, document.getElementById('root'))

Slide 20

Slide 20 text

main(Kotlin) fun main(args: Array) { // cssファイルの読み込み requireAll(require.context("src", true, js("/\\.css$/"))) render(document.getElementById("root")) { app() } }

Slide 21

Slide 21 text

render(JavaScript) class App extends Component { constructor() { … } render() { return (

todoアプリを作ってみた

); } }

Slide 22

Slide 22 text

render(Kotlin) class App : RComponent() { override fun AppState.init() { ... } override fun RBuilder.render() { div( classes = "app" ) { h1 { +"todoアプリを作ってみた" } todoList(state.todoList) } } }

Slide 23

Slide 23 text

List Rendering

Slide 24

Slide 24 text

List Rendering(JavaScript) class TodoList extends Component { render() { const todos = this.props.todos.map( todo => ) return(
    {todos}
); } }

Slide 25

Slide 25 text

List Rendering(Kotlin) class TodoListComponent(props: TodoListProps): RComponent(props) { override fun TodoListState.init(props: TodoListProps) { todoList = props.todoList.toMutableList() } override fun RBuilder.render() { val todos = props.todoList.map { todo(it, props.setTodoStatus) } ul { todos } } }

Slide 26

Slide 26 text

State

Slide 27

Slide 27 text

State(JavaScript) class App extends Component { constructor() { super() this.state = { todos: [ { id: 1, title: "Hello, React!", desc: "React始めました", done: false }, ... ] } } render() { ... } }

Slide 28

Slide 28 text

State(Kotlin) interface AppState: RState { var todoList: MutableList var countTodo: Int } class App : RComponent() { override fun AppState.init() { todoList = mutableListOf( Todo(1, "Hello, React!", "React始めました"), Todo(2, "Hello, Redux!", "Reduxも始めました") ) } override fun RBuilder.render() { ... } }

Slide 29

Slide 29 text

Props

Slide 30

Slide 30 text

Props(JavaScript) class Todo extends Component { render() { const className = 'undone' const link = this.props.done ? '元に戻す' : '完了!' return(
  • {this.props.id} :{this.props.title}   {link}

    {this.props.desc}

  • ); } }

    Slide 31

    Slide 31 text

    Props(Kotlin) interface TodoProps: RProps { var todo: Todo var setTodoStatus: (Todo) -> Unit } class TodoComponent(props: TodoProps): RComponent(props) { override fun RBuilder.render() { val className = if(props.todo.done) "undone" else "done" val link = if(props.todo.done) "元に戻す" else "完了!" ... } } fun RBuilder.todo(todo: Todo) = child(TodoComponent::class) { attrs.todo = todo }

    Slide 32

    Slide 32 text

    Handling Event

    Slide 33

    Slide 33 text

    Handling Event(JavaScript) class Todo extends Component { render() { ... return( ... { e.preventDefault(); this.props.setTodoStatus(this.props)}}>{link}   ... ); } }

    Slide 34

    Slide 34 text

    Handling Event(Kotlin) class TodoComponent(props: TodoProps): RComponent(props) { override fun RBuilder.render() { ... a(href = "#") { +link attrs { onClickFunction = { e -> e.preventDefault() this@TodoComponent.props.setTodoStatus(this@TodoComponent.props.todo) } } } ... } } }

    Slide 35

    Slide 35 text

    Reduxを導入してみる

    Slide 36

    Slide 36 text

    Reduxを導入してみる 状態管理フレームワークのreduxやreact-reduxのKotlinラッパーも用意されています。 npm install @jetbrains/kotlin-redux npm install @jetbrains/kotlin-react-redux 以下のコマンドを実行することでIntellJ Ideaで上のライブラリをモジュールとして認識さ せることができる npm run gen-idea-libs

    Slide 37

    Slide 37 text

    まとめ

    Slide 38

    Slide 38 text

    まとめ ● 無理やり感はなく、普段のReactのように書ける ● Kotlinのモダンな言語仕様を利用してフロントが書ける ● TypeSafeにフロントをかけるのは良い (TypeScriptでいいのでは?) ● サーバーサイドもフロントもAndroidも同じ言語で書ける ● KotlinでReactが書けるってことはKotlinでReact Nativeも…!? JetBrains/kotlin-wrappers https://github.com/JetBrains/kotlin-wrappers Kotlin JS OverView https://kotlinlang.org/docs/reference/js-overview.html