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)