$30 off During Our Annual Pro Sale. View Details »

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

44
September 19, 2018

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

44

September 19, 2018
Tweet

More Decks by 44

Other Decks in Technology

Transcript

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

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

    まとめ
  3. 自己紹介 ヤマサキ ヨシヒロ 山崎 好洋 ヤフー18年度 新卒 • Vue.js •

    DDD • TDD • モブプロ • Kotlin @44x1carbon
  4. Vue.jsしか触ってこなかったから Reactを触ってみよう!!

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

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

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

  8. コマンドでプロジェクトの雛形を作成 1. コマンドのインストール npm install -g create-react-kotlin-app 2. プロジェクトの作成 create-react-kotlin-app

    todo-list ※実行前にJDK8をインストールしておく必要があります。
  9. プロジェクトのディレクトリ構造

  10. 実行は npm start

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

  12. None
  13. Kotlinの言語仕様紹介(少しだけ)

  14. コンストラクタ プライマリコンストラクタはクラスヘッダ部分に書きます class Person constructor(val firstName: String) { ... }

    アノテーションやアクセス修飾子がない場合はconstructorキーワードを省略できます class Person(val firstName: String) { ... }
  15. 拡張メソッド 既存の型にメソッドを追加することができます。 fun 拡張したい型.拡張メソッド名 例) fun String.toNewLine() = this +

    “\n” “Hoge”.toNewLine()
  16. 引数の最後にラムダを渡す時の省略記法 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) }
  17. kotlin-reactでどう書く? 1. Rendering 2. List Rendering 3. State 4. Props

    5. Handling Event
  18. Rendering

  19. main(JavaScript) import './css/index.css' import React from 'react' import ReactDOM from

    'react-dom' import App from './App' ReactDOM.render(<App />, document.getElementById('root'))
  20. main(Kotlin) fun main(args: Array<String>) { // cssファイルの読み込み requireAll(require.context("src", true, js("/\\.css$/")))

    render(document.getElementById("root")) { app() } }
  21. render(JavaScript) class App extends Component { constructor() { … }

    render() { return ( <div className="app"> <h1>todoアプリを作ってみた</h1> <TodoList todos={this.state.todos} /> </div> ); } }
  22. render(Kotlin) class App : RComponent<RProps, AppState>() { override fun AppState.init()

    { ... } override fun RBuilder.render() { div( classes = "app" ) { h1 { +"todoアプリを作ってみた" } todoList(state.todoList) } } }
  23. List Rendering

  24. List Rendering(JavaScript) class TodoList extends Component { render() { const

    todos = this.props.todos.map( todo => <Todo key={todo.id} {...todo} /> ) return( <ul> {todos} </ul> ); } }
  25. List Rendering(Kotlin) class TodoListComponent(props: TodoListProps): RComponent<TodoListProps, TodoListState>(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 } } }
  26. State

  27. State(JavaScript) class App extends Component { constructor() { super() this.state

    = { todos: [ { id: 1, title: "Hello, React!", desc: "React始めました", done: false }, ... ] } } render() { ... } }
  28. State(Kotlin) interface AppState: RState { var todoList: MutableList<Todo> var countTodo:

    Int } class App : RComponent<RProps, AppState>() { override fun AppState.init() { todoList = mutableListOf( Todo(1, "Hello, React!", "React始めました"), Todo(2, "Hello, Redux!", "Reduxも始めました") ) } override fun RBuilder.render() { ... } }
  29. Props

  30. Props(JavaScript) class Todo extends Component { render() { const className

    = 'undone' const link = this.props.done ? '元に戻す' : '完了!' return( <li className={className}> <span>{this.props.id}</span> <span>:{this.props.title}  </span> <a href="">{link}</a> <p>{this.props.desc}</p> </li> ); } }
  31. Props(Kotlin) interface TodoProps: RProps { var todo: Todo var setTodoStatus:

    (Todo) -> Unit } class TodoComponent(props: TodoProps): RComponent<TodoProps, RState>(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 }
  32. Handling Event

  33. Handling Event(JavaScript) class Todo extends Component { render() { ...

    return( ... <a href="" onClick={(e) => { e.preventDefault(); this.props.setTodoStatus(this.props)}}>{link}</a>   ... ); } }
  34. Handling Event(Kotlin) class TodoComponent(props: TodoProps): RComponent<TodoProps, RState>(props) { override fun

    RBuilder.render() { ... a(href = "#") { +link attrs { onClickFunction = { e -> e.preventDefault() this@TodoComponent.props.setTodoStatus(this@TodoComponent.props.todo) } } } ... } } }
  35. Reduxを導入してみる

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

    せることができる npm run gen-idea-libs
  37. まとめ

  38. まとめ • 無理やり感はなく、普段の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