LoginSignup
47
43

More than 5 years have passed since last update.

Reduxさわってみたのでメモ 【middleware, ログ、非同期処理】

Posted at

redux-loggerを使ってみる

redux-logger

Stateがどう変わったか、及びどのActionがdispatchされたことによるか、をログとして表示してくれるMiddleware

ソースみてもわかるように、

redux-logger/blob/master/src/index.js
    if (level) {
      console[level](`%c prev state`, `color: #9E9E9E; font-weight: bold`, prevState);
      console[level](`%c action`, `color: #03A9F4; font-weight: bold`, formattedAction);
      console[level](`%c next state`, `color: #4CAF50; font-weight: bold`, nextState);
    } else {
      console.log(`%c prev state`, `color: #9E9E9E; font-weight: bold`, prevState);
      console.log(`%c action`, `color: #03A9F4; font-weight: bold`, formattedAction);
      console.log(`%c next state`, `color: #4CAF50; font-weight: bold`, nextState);
    }

以下のようなログを表示してくれる

687474703a2f2f692e696d6775722e636f6d2f7168637a314f442e706e67.png

version

  • 2.0.2

install

npm install --save redux-logger

usage

index.js
import createLogger from 'redux-logger';

const logger = createLogger();
const createStoreWithMiddleware = applyMiddleware(logger)(createStore);
const store = createStoreWithMiddleware(reducer);

オプションもいろいろあるようです

index.js
const logger = createLogger({
  // 特定の種別のアクション以外のログを表示する
  predicate: (getState, action) => action.type !== AUTH_REMOVE_TOKEN,
  // ログレベルを指定 
  level: 'info',
  // 一連の処理にかかった時間を表示するか
  duration: true 
});

memo

普通にREADME.mdみれば問題なく動くはずなのだけど、自分は

を参考にしながら実装してしまったのですが、redux-loggerのバージョンが0.0.3とかなり古く、少しハマってしまいました(下のコメント部分)

configureStore.js
import thunkMiddleware from 'redux-thunk';
import loggerMiddleware from 'redux-logger';
import rootReducer from '../reducers';

const createStoreWithMiddleware = applyMiddleware(
  thunkMiddleware,
  loggerMiddleware // loggerMiddleware() のように関数ではない!!!
)(createStore);

export default function configureStore(initialState) {
  const store = createStoreWithMiddleware(rootReducer, initialState);

  // ...

isomorphic-fetchを使ってみる

さきほどのサンプルのAsyncでは非同期処理にisomorphic-fetchを使用していたので、それに倣って使ってみた

version

  • isomorphic-fetch => 2.1.1
  • es6-promise => 3.0.2

es6-promisepromise使うためのポリフィル

install

npm install --save isomorphic-fetch es6-promise

usage

SomeComponent.js
  componentDidMount() {
    fetch('http://localhost:7000/list')
      .then(response => response.json())
      .then(json => store.dispatch(Actions.updateList(json)));

    // ...

こんな感じで、非同期処理でデータを引っ張ってきて、そのデータを引数にActionをdispatchする、というのは特に迷うことなくできたのですが・・・サンプルではActionの中に非同期処理を入れ込んでいるようです。

ということで、サンプルに倣って新規に追加したActionをdispatchするよう修正してみっところ、

Action.js
export function fetchList = () => {
  return dispatch => {
    return fetch('http://localhost:7000/list')
      .then(response => response.json())
      .then(json => dispatch(Actions.updateList(json)));
  };
}

以下のエラーがでました

Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.

内容は御尤ものことで、Actionはオブジェクトでないとダメというもの

redux-thunkを使ってみる

version

  • 1.0.0

install

npm install --save redux-thunk

usage

Middlewareに追加する

index.js
import createLogger from 'redux-logger';
import thunk        from 'redux-thunk';

const logger = createLogger();
const createStoreWithMiddleware = applyMiddleware(thunk, logger)(createStore);
const store = createStoreWithMiddleware(reducer);

メモ

redux-thunkMiddlewareとして追加することで、さきほどのActions must be plain objectsというエラーはでなくなり、非同期処理・データフローも正しい挙動になりました。

また、このMiddlewareってコードでいうとたったのこれだけなので、アイデアあれば結構簡単にMiddlewareつくれるかなぁと勇気をもらった

redux-thunk/blob/master/src/index.js
export default function thunkMiddleware({ dispatch, getState }) {
  return next => action =>
    typeof action === 'function' ?
      action(dispatch, getState) :
      next(action);
}
47
43
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
47
43