初心者のプログラミング日記

プログラミング初心者の日記

プログラミングに関することを書いていきます。

React+ReduxでTodoアプリを作る。完成

今回でTodoアプリを完成させます

前回まで
nasubifx.hatenablog.com

ファイル構成は前回と同じなので省きます

まずActions.jsから

//Actions.js
const ADD_TODO="ADDTODO";
const REMOVE_TODO="REMOVETODO";

const removetodo=(id)=>{
    return{type:REMOVE_TODO,id}
}

export {addtodo,removetodo};
export {ADD_TODO,REMOVE_TODO};

削除するためにアクションを追加します

次にReducers.jsです

import { combineReducers } from "redux";
import {ADD_TODO,REMOVE_TODO} from './Actions';

const initialState = {todos:[]};

let id=0;
//Reducer
const Todo = (state=initialState, action) => {
    switch (action.type) {
      case ADD_TODO:
        return{...state,todos:[...state.todos,{todo:action.text,id:id++}]}

      case REMOVE_TODO:
        const newtodo=[...state.todos];
        const index=state.todos.findIndex(int=>int.id===action.id);
        if(index>-1){
          newtodo.splice(index,1)
        }
        return{...state,todos:newtodo}

      default:
          return state;
    }
  };

const  reducers=combineReducers({Todo});
export default reducers;

今回はstateの初期値をオブジェクトにしてみましたが、オブジェクトでも配列でもどちらでも変わらなかったです。
削除するtodoを特定するためidを追加しています。
REMOVE_TODOの場合にif文を入れていますがなくてもいいです。

次にApp.jsです

//App.js
import React from 'react';
import { connect } from 'react-redux'
import {addtodo,removetodo} from './Actions';
import './App.css';

class App extends React.Component{
    constructor(props){
        super(props);
       this.inputtext=React.createRef();
       this.submit=this.submit.bind(this);
    }

    submit(e){
        e.preventDefault();
        this.props.ADDTODO(this.inputtext.current.value);
        this.inputtext.current.value="";

    }

    render(){
        const todolist=this.props.todo.todos.map((todo)=>{
        return(<li key={todo.id}>{todo.todo}
                 <i className="fas fa-trash-alt" onClick={()=>this.props.REMOVETODO(todo.id)}></i>
               </li>)})
      return(
          <div>
              <form onSubmit={this.submit}>
                  <label>
                      <p>>新しいTodoを追加</p>
                      <input tyoe='text' ref={this.inputtext}/>
                  </label>
                  <button type='submit'>追加</button>
              </form>
              <ul>
                  {todolist}
              </ul>
          </div>
      );
    }
  }
  

const mapStateToProps = (state) =>{
  return {todo:state.Todo}
}

const mapDispatchToProps = (dispatch) =>(
    {
        ADDTODO:(text)=>dispatch(addtodo(text)),
        REMOVETODO:(index)=>dispatch(removetodo(index))
    }
)
  
export default connect(mapStateToProps,mapDispatchToProps)(App);

stateをオブジェクトにしたことにより若干map関数が変わっています。
前回の記事では書いていなかったのですが、ReactではKeyの値はindex番号は望ましくないため、idを追加してkeyに当てています。
今回は削除ボタンfontawesomeから持ってきました。
https://fontawesome.com/icons/trash-alt

最後にindex.jsです

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux'; 
import { Provider } from 'react-redux';
import App from './App';
import reducers from './Reducers';
import * as serviceWorker from './serviceWorker';
 
const  store = createStore(reducers);
 
ReactDOM.
render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
serviceWorker.unregister();

特に変更はないです。

これで一応、Todoアプリの最低限の機能はつけられたと思います。