[Redux]Redux操作手順



Ducksモード、動作タイプ、動作生成関数、リダイレクトを記述するコードを使用したサンプルモジュールを作成し、リダイレクト操作の順序を理解します.

1.アクションタイプの定義


まず、動作タイプを定義します.
const CHANGE_INPUT = 'todos/CHANGE_INPUT'; // 인풋 값을 변경함
const INSERT = 'todos/INSERT'; // 새로운 todo를 등록함
const TOGGLE = 'todos/TOGGLE'; // todo를 체크/체크 해제함
const REMOVE = 'todos/REMOVE'; // todo를 제거함

2.アクション作成関数の作成


次に、アクション生成関数を作成します.
(...)

 export const changeInput = input => ({
   type: CHANGE_INPUT,
   input
 });

let id = 3; // insert가 호출될 때마다 1씩 더해진다.
export const insert = text => ({
  type: INSERT,
  todo: {
    id: id++,
    text,
    done: false
  }
});

export const toggle = id => ({
  type: TOGGLE,
  id
});

export const remove = id => ({
  type: REMOVE,
  id
});

3.初期状態とreducer関数の作成


次に,モジュールの初期状態とreducer関数を記述する.このとき不変性を保つように注意します.
(...)
const initialState = {
 input: '',
 todos: [
         {
           id: 1,
           text: '리덕스 기초 배우기',
           done: true
         },
  	 {
           id: 2,
           text: '리액트와 리덕스 사용하기',
           done: false
         },
        ]
};

function todos(state = initialState, action) {
  switch (action.type) {
    case CHANGE_INPUT:
      return {
        ...state,
        input: action.input
      };
    case INSERT:
      return {
        ...state,
        todos: state.todos.concat(action.todo)
      };
    case TOGGLE:
      return {
        ...state,
        todos: state.todos.map(todo =>
          todo.id === action.id ? {...todo, done: !todo.done} : todo
        )
      };
    case REMOVE:
      return {
        ...state,
        todos: state.todos.filter(todo => todo.id !== action.id)
    default:
      return state;
  }
}

export default todos;

4.スーパーユーザーの作成


Reduserは一般的に1つだけではなく、多くのことをします.後でcreateStore関数を使用してショップを作成する場合は、Reducerを1つだけ使用する必要があるため、Reducerを1つにマージする必要があります.この作業は、Ridexが提供する組合せReducerという実用的な関数を使用することで簡単に行うことができます.
たとえば、モジュールディレクトリにcounterモジュールとtodosモジュールがある場合は、次のコードを記述できます.
// modules/index.js
import { combineReducers } from 'redux';
import counter from './counter';
import todos from './todos';

const rootReducer = combineReducers({
  counter,
  todos,
});

export default rootReducer;
ファイル名はこのようにindexしますjsに設定すると、後でロードするときにディレクトリ名しか入力できません.
import rootReducer form './modules';

5.ショップの作成


ショップを作成し、応答アプリケーションにリカバリを適用する操作は、srcディレクトリのindexです.jsで実現します.
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import rootReducer from './modules';

const store = createStore(rootReducer);

ReactDOM.render(<App />, document.getElementById('root'));

serviceWorker.unregister();

6.Provider素子を使用して放射線をプロジェクトに適用する


アプリケーションコンポーネントをreact-reduceが提供するプロバイダコンポーネントにカプセル化し、応答コンポーネントでショップを使用します.この構成部品を使用する場合は、storeをpropsに渡す必要があります.
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import rootReducer from './modules';

const store = createStore(rootReducer);

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

serviceWorker.unregister();

7.コンテナ構成部品の作成


次に、構成部品はリカバリポイントにアクセスし、必要なステータスを取得し、アクションを送信します.リカバリポイントに関連付けられた構成部品をコンテナ構成部品と呼びます.この場合、容器素子をリデスと連動させるには、react-reduxが提供するconnect関数を使用する必要があります.connect関数が呼び出されると、別の関数が返されます.戻り関数にエレメントをパラメータとして入れると、ガイドに関連付けられたエレメントが作成されます.
const makeContainer = connect(mapStateToProps, mapDispatchToProps)
makeContainer(타깃 컴포넌트)
import React from 'react';
import { connect } from 'react-redux';
import Counter from '../components/Counter';
import { increase, decrease } from '../modules/counter';

const counterContainer = ({ nunber, increase, decrease }) => {
  return (
    <Counter number={number} onIncrease={increase} onDecrease={decrease} />
  );
};

const mapStateToProps = state => ({
  number: state.counter.number,
});

const mapDispatchToProps = dispatch => ({
  // 임시 함수
  increase: () => {
	dispatch(increase());
  },
  decrease: () => {
    dispatch(decrease());
  },
});
export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(CounterContainer);                         
ここで、mapStateToPropsは、復元点内の状態を素子のpropsに移行するために設けられた関数であり、mapDispatchToPropsは、動作生成関数を素子のpropsに移行するために用いられる関数である.mapStateToPropsおよびmapDispatchToPropsから返されるオブジェクト内部の値は、アセンブリの支柱に渡される.mapStateToPropsはstateをパラメータとして受け入れ、この値は商店の現在の状態を表す.mapDispatchToPropsの場合、storeの内蔵関数dispatchはパラメータとして受信される.connect関数を使用する場合、mapStateToPropsおよびmapDispatchToPropsは、通常、上記のコードのように予め宣言される.ただし、connect関数の内部で匿名関数として宣言しても問題ありません.次のように書くこともできます.
import React from 'react';
import { connect } from 'react-redux';
import Counter from '../components/Counter';
import { increase, decrease } from '../modules/counter';

const counterContainer = ({ nunber, increase, decrease }) => {
  return (
    <Counter number={number} onIncrease={increase} onDecrease={decrease} />
  );
};

export default connect(
  state => ({
    number: state.counter.number,
  }),
  dispatch => ({
    increase: () => dispatch(increase()),
    decrease: () => dispatch(decrease()),
  }),
)(CounterContainer);
一気にきれいになった.しかし、このように構成部品でdispatch動作のために各動作生成関数を呼び出し、dispatchで包む操作は面倒である可能性がある.特に,動作生成関数の個数が多くなるとなおさらである.この場合、reduceが提供するbindActionCreatorsユーティリティ関数を使用するのは簡単です.
import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import Counter from '../components/Counter';
import { increase, decrease } from '../modules/counter';

const counterContainer = ({ nunber, increase, decrease }) => {
  return (
    <Counter number={number} onIncrease={increase} onDecrease={decrease} />
  );
};

export default connect(
  state => ({
    number: state.counter.number,
  });
  dispatch =>
    bindActionCreators(
      {
        increase,
        decrease,
      },
      dispatch,
   ),
)(CounterContainer);
でもこれよりもっと便利な方法がありますこれなら都合のいいことだけ教えていただけないでしょうか.すなわち,mapDispatchToPropsに対応するパラメータを関数形式ではなく動作生成関数からなるオブジェクトに入れる.
import React from 'react';
import { connect } from 'react-redux';
import Counter from '../components/Counter';
import { increase, decrease } from '../modules/counter';

const counterContainer = ({ nunber, increase, decrease }) => {
  return (
    <Counter number={number} onIncrease={increase} onDecrease={decrease} />
  );
};

export default connect(
  state => ({
    number: state.counter.number,
  }),
  {
    increase,
    decrease,
  },
)(CounterContainer);
前述したように、2番目のパラメータを直接オブジェクト形式で配置すると、connect関数は、bindActionCreatorsの代わりに内部で動作する.