LoginSignup
0
1

More than 1 year has passed since last update.

Reduxを完全に理解した(〜実装編〜)

Last updated at Posted at 2023-02-20

Reduxの理論編に引き続き実装編について説明していきます:alien:

↓↓↓ 理論編についてはこちら ↓↓↓


ではコードをもとに説明をしていきます。
今回は簡単なTODOアプリでTODOの追加・削除のみできるものを想定しています。

Reducer

まずは「Reducer」についてですが、理論編で説明したように「Reducer」は渡されてきた「Action」と現在の状態から新しい「State」を作成し返しています。
→「純粋関数」で副作用もないですね:clap:

reducers.js
import { combineReducers } from 'redux';

export function todoReducers(state={
  list: []
}, action) {
  switch (action.type) {
    case "ADD_TODO":
      return Object.assign({}, state, {
        list: state.list.concat(action.todo)
      });
    case "REMOVE_TODO":
      return Object.assign({}, state, {
        list: state.filter(todo => {
          return action.todo != todo;
        })
      });
    default:
      return state;
  }
};

export default combineReducers({todoReducers});

Action

次にActionですが、これはReducerに渡す情報を返すだけの処理になっています。
TODOを追加する処理と、削除する処理があるのでそれぞれのActionを作成しています。

action.js
export function addTodo(todo) {
  return {
    type: "ADD_TODO",
    todo
  }
}

export function removeTodo(todo) {
  return {
    type: "REMOVE_TODO",
    todo
  }
}

Store

これに関しては、Storeを作成しているだけですね:point_up:

store.js
import { createStore } from 'redux';
import reducers from './reducers';

const store = createStore(reducers);

export default store;

Entry部分

index.jsについては最初のEntryの部分で、コンポーネントの一番親と言っていい部分です。
またProviderとありますが、Providerはpropsで子コンポーネントに渡さずとも、コンポーネントツリー内でデータを渡すことができるものとなっています。

index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
import registerServiceWorker from './registerServiceWorkder';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>
 ,document.getElementById('root')
);

registerServiceWorker();

App(実際のTODOアプリメイン処理)

先ほど、providerをindex.jsで使用しているので、mapStateToPropsのようなfunctionを作成しStoreの中身をバケツリレーでなくとも受け取ることができます。
追加処理については、テキストボックスの中身に変更が加わると、このコンポーネント(App)内の「State」にセットします。そして、追加ボタンを押すとその「State」を「Action」に詰めて「Dispatch」します。

削除処理についても「Action」に詰めて「Dispatch」するところは同様で、「Store」内の「State」のTODOリストでループして、各TODOを「Action」に詰めて「Dispatch」しています。

App.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { addToDo, removeToDo } from './actions';
import store from './store';

class App extends Component {
    constructor() {
        super();
        this.state = {
            input: ""
        };
    }

    render() {
        <div>
            <ul>
                {this.props.todos.map(todo => {
                    return (
                        <li key={todo}>
                            <span>{todo}</span>
                            <button onClick={() => {this.props.dispatch(removeToDo(todo))}}>削除</button>
                        </li>
                    );
                })}
            </ul>

            <input type="text" onChange={e => this.setState({input: e.target.value})} />
            <button onClick={() => this.props.dispatch(addToDo(this.state.input))}>追加</button>
        </div>
    }
}

const mapStateToProps = state => {
    return {
        todos: state.todos.list
    }
};

export default connect(mapStateToProps)(App);

まとめ

思ったより難しくなかったですよね:point_up:
ただ、ReducerやStateの数が増えたりすると、そのたくさんあるReducer・Stateをどう分割していくかが難しかったりします。
この記事を参考にReduxの知識をつけてもらえますと幸いです。

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