Open4

Redux

ゆうとゆうと

このやり方は非推奨。
createContext,useContextの代わりにcreateStore、
,useReducerの代わりにuseSelector,useDispatchを使う。

ゆうとゆうと

redux thunk

概要

非同期処理(副作用)を捌くredux middlewareの一つ。
storeのreducerの前に呼ばれ、その中で前述の処理を行う。
最後にdispatchで、reducerを呼ぶ。

書き方

const thunkFunction = (payload) => {
   return (dispatch, getState) => {
    副作用処理  
   }
 }

dispatchはreducerを呼ぶ。getStateは現在の状態を呼ぶ関数。
payloadでわたってきた任意の値を非同期処理する。

具体的な使い方

const addAsync = (payload) => {
  return async (dispatch, getState) => {
    const state = getState();
    console.log(state);
    const response = await asyncCount(payload);
    dispatch(add(response.data));
  }
}

非同期処理なので、async awaitを忘れない。

const asyncCount = (count = 1) => {
  return new Promise((resolve) =>
    setTimeout(() => resolve({ data: count }), Math.random() * 1000)
  );
};
export { asyncCount };

payloadがasyncCountのcountに渡ってきて、setTimeoutのランダム秒過ぎたら、resolveを実行する。
resolveがresponseにわたるので、dispatchでreducerを呼ぶ。

ゆうとゆうと

createAsyncThunkを使う。

第1引数にtypeを渡す。
第2引数が非同期処理。returnで返すことを忘れずに。

const addAsyncWithStatus = createAsyncThunk(
  'counter/asyncCount',
  async (payload) => {
    const response = await asyncCount(payload);
    return response.data;
  }
)
extraReducers: (builder) => {
    builder.addCase(addAsyncWithStatus.pending, (state) => {
      state.status = 'Loading...'
    })
    .addCase(addAsyncWithStatus.fulfilled, (state, action) => {
      state.status = '取得済'
      state.count = state.count + action.payload;
    })
    .addCase(addAsyncWithStatus.rejected, (state) => {
      state.status = 'エラー'
    })
  }

storeの中に、extraReducersを定義。
addCaseで処理を条件分岐。
関数がpending(待機中)、fulfilled(実行済み)、rejected(エラー)で処理を場合分け。
state.statusのstatusはintialStateで定義済み。

ゆうとゆうと

redux Middleware

使い方

クロージャーによって、外側の関数の引数が関数として、内側で使用可能。

const reduxMiddleware = (store) => {
  return (next) => {
    return (action) => {
      // 全てのdispatchで行われる処理
      // storeはaction前の状態
      // (store.getState()でステートを取得)
      next(action);
      // storeはaction後の状態
    };
  }
}
export default configureStore({
  reducer: {
    counter: reducer
  },
  middleware: (getDefaultMiddleware) => {
    const middlewares = getDefaultMiddleware();
    const newMiddlewares = middlewares.concat(logger)
    return newMiddlewares;
  }
});

作ったmiddlewareをstoreに渡す。
ただし以上の書き方ではなく、省略技法があるのでそれをいかに貼ります。

middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger)