1
1

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.

ReduxのサンプルのTodoリストを真似てみる。Part.5

1
Last updated at Posted at 2018-06-01

ReduxのサンプルのTodoリストを真似てみる。Part.4の続きです。
前回のサンプルに、redux-undoでUndo/Redo機能をつける

0.留意点

  • 前回の記事から、Reduxのサンプル "todos-with-undo"とおなじ機能を付けてみた。
  • 初心者の覚書です。
  • 自分の環境で動くように参考にしたコードを適当に修正している。
  • Windows10 64bit , PowerShellなどで動かしている。
  • 見栄えを若干よくする為にbootstrap4を利用している。
  • 前回から、見やすくするため、bootstrapの設定や、DOMの表示上の並びを変更してある
  • redux-undo 関係だけを記述する

1.redux-undoのインストール

redux-undoのGitHubにあるように、素直にしたがう。

PowerShellコンソール
npm install --save redux-undo@beta

はじめ、@beta をつけずにインストールしたが、いろいろ具合が悪かった。

reducersをredux-undo対応にする。

もともとの todosリデューサーをundoableでラップする。
これで

state.todos.past
state.todos.present
state.todos.future

などが使えるようになる。

reducers\todo.js
import undoable, { includeAction } from 'redux-undo';

const todos = (state = [], action) => {
    switch (action.type) {
        case 'ADD_TODO':
            return [...state,
            {
                id: action.id,
                text: action.text,
                completed: false
            }
            ]
        case 'TOGGLE_TODO':
            return state.map(
                (todo) => {
                    if (action.id !== todo.id) {
                        return todo;
                    } else {
                        return  Object.assign({},todo,{completed:!todo.completed});
                    }
                }
            );
        default:
            return state;
    }
}

const undoableTodos = undoable(todos, { filter: includeAction(['ADD_TODO', 'TOGGLE_TODO']) });
export default undoableTodos;

UndoRedoコンテナをつくる

UndoRedoコンポーネントをconnectでラップ。

mapDispatchToProps がオブジェクトであることに注意。
connectの第二引数を関数にして、エラーがでた。仕様上、関数をうける場合、オブジェクトを受ける場合の2通りあるようだが、こっちはオブジェクトらしい。

containers\UndoRedo.js
import React from 'react';
import { connect } from 'react-redux';
import { ActionCreators as UndoActionCreators, ActionCreators } from 'redux-undo';

let UndoRedo = ({ canUndo, canRedo, onUndo, onRedo }) => (
    <div className="mb-1">
        <button className="btn btn-info mr-3" onClick={onUndo} disabled={!canUndo}>元に戻す</button>
        <button className="btn btn-info" onClick={onRedo} disabled={!canRedo}>やり直す</button>
    </div>
)

const mapStateToProps = (state) => {
    return {
        canUndo: state.todos.past.length > 0,
        canRedo: state.todos.future.length > 0
    }
}

const mapDispatchToProps = {
    onUndo: UndoActionCreators.undo,
    onRedo: UndoActionCreators.redo
}

UndoRedo = connect(mapStateToProps, mapDispatchToProps)(UndoRedo);

export default UndoRedo;

AppコンポーネントにUndoRedoコンテナを追加

components\App.js
import React from 'react';
import VisibleTodoList from '../containers/VisibleTodoList';
import AddTodo from '../containers/AddTodo';
import Footer from "./Footer";
import UndoRedo from "../containers/UndoRedo";

//classNameでBootsrapに関する設定
const App = () => (
    <div>
        <h1 className="text-center alert alert-info ">Todoリスト</h1>
        <UndoRedo />
        <Footer />
        <VisibleTodoList />
        <AddTodo />
    </div>
)

export default App;

実行結果

ソースコード 09

補足

reducers\visibilityFilter.js にフィルターのりデューサもあり、todosと同様にundo/redoに組み込んでみたが、todosと干渉してか、不審な挙動をするので外した。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?