16
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

React + Redux + TypeScriptとImmutable.js

Last updated at Posted at 2016-06-25

こちらの記事の続編です。
http://qiita.com/uryyyyyyy/items/30733e9cd140e60c52bd

問題提起

今時、型のない言語とか使いたくないですよね!(JSerにケンカ売る挨拶)
今回はtodoListのサンプルを通じて、immutableJSの良さを再確認しましょう。

環境

  • NodeJS 5.x~
  • React 15.1
  • TypeScript 1.8

構成

こちらをご参照ください。
https://github.com/uryyyyyyy/react-redux-sample/tree/immutable

Immutable.jsとは

JSでListやMapなどのコレクションを扱えるもの。
TypeScriptで使うと、ネイティブのArrayやObjectと比べて使えるメソッドが増えるのでオススメです。
(逆にJSで使うのであれば、ネイティブの型と混同しがちなのでlodashとかの方が良いのではないでしょうか?)

npm install immutable --save
typings install dt~immutable --global --save

ネイティブ型の場合

let list:number[] = [1, 2]

//そんなものはない。
list.isEmpty()

list.push(3)
list // [1,2,3] 破壊的メソッドコワイ

Immutable.jsのList型の場合

import {List} from "immutable";

let list:List<number> = List.of<number>(1, 2)

//ある!
list.isEmpty()

let newList = list.push(3)
list // [1,2] Immutable!

Immutable.jsでTodoList

基本コードを見てもらったほうが早いように思いますが、要点だけ。

src/todo/Reducer.ts

const initialState:TodoState = {todos: List.of<Todo>(), marks: marks};

export function todoReduce(state: TodoState = initialState, action: MyAction): TodoState {

    function changeStatus(state: TodoState, action: MyAction):TodoState {
        const newTodos = state.todos.map(v => {
            if (v.id === action.id) return new Todo(v.id, v.text, !v.isComplete);
            return v
        });
        return objectAssign({}, state, {todos: newTodos});
    }

    function addTodo(state: TodoState, action: MyAction):TodoState {
        let newNumber = 1;
        if(!state.todos.isEmpty()) newNumber = state.todos.map(v => v.id).max() + 1;
        const newTodo = new Todo(newNumber, action.text, false);
        return objectAssign({}, state, {todos: state.todos.push(newTodo)});
    }

    function deleteTodo(state:TodoState, action:MyAction):TodoState {
        return objectAssign({}, state, {todos: state.todos.filter(item => item.id !== action.id)});
    }
}
src/todo/TodoItem.tsx
export interface Props {
    /* ... */
    marks: Map<boolean, string>
}

render () {
        return (
            <li>
                <span>{this.props.marks.get(this.props.item.isComplete)}:  {this.props.item.text} </span>
         /* ... */
        );
    }

どうですか。Immutable.Listのおかげで綺麗に書けてる気がしませんか?
(うーん。。この例だと言うほど便利じゃなさそうかも?まぁ、SetやStackなど色々な便利コレクションが同梱されているので、それ系に慣れている方だとかなり便利かと思います。)

注意点としては、jsonサーバーとの通信で来るjsonは勝手にImmutable.jsのオブジェクトにならないので、都度変換する必要があります。

  const json: TodoInterface[] = [
    {id: 1, text: "todo 1", isComplete: true},
    {id: 2, text: "todo 2", isComplete: false}
  ];
  const todos: List<TodoInterface> = List.of(...json);

逆にimmutable.jsオブジェクトからjsonへの変換は期待通りになります。

16
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?