728x90
//asyncActions.js
const { createStore, applyMiddleware } = require('redux');
const thunkMiddleware = require('redux-thunk').default;
const axios = require('axios');
const FETCH_USERS_REQUEST = 'FETCH_USERS_REQUEST';
const fetchUsersRequest = () => ({
type: FETCH_USERS_REQUEST,
});
const FETCH_USERS_SUCCESS = 'FETCH_USERS_SUCCESS';
const fetchUsersSuccess = (users) => ({
type: FETCH_USERS_SUCCESS,
users,
});
const FETCH_USERS_ERROR = 'FETCH_USERS_ERROR';
const fetchUsersError = (error) => ({
type: FETCH_USERS_ERROR,
error,
});
const initialState = {
loading: false,
users: [],
error: '',
};
const fetchUsers = () => {
return function (dispatch) {
dispatch(fetchUsersRequest());
axios
.get('https://jsonplaceholder.typicode.com/users')
.then((res) => {
const users = res.data.map((user) => user.id);
dispatch(fetchUsersSuccess(users));
})
.catch((error) => {
dispatch(fetchUsersError(error.message));
});
};
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case FETCH_USERS_REQUEST:
return {
...state,
loading: true,
users: [],
error: '',
};
case FETCH_USERS_SUCCESS:
return {
...state,
loading: false,
users: action.users,
error: '',
};
case FETCH_USERS_ERROR:
return {
...state,
loading: false,
users: [],
error: action.error,
};
default:
return state;
}
};
const store = createStore(reducer, applyMiddleware(thunkMiddleware));
console.log('intial state : ' + store.getState());
const unsubscribe = store.subscribe(() => {
console.log(store.getState());
});
store.dispatch(fetchUsers());
기존 redux에서 async action처리를 위한 redux thunk middleware를 접목한 구현은 다음과 같다.
action을 직접 호출하는 대신 thunk를 호출하면 thunk 내에서 action을 호출하여 reducer에서 그에 맞는 state를 반영하는 개념이었다.
redux-toolkit도 크게 다르지 않다. redux와 크게 다르게 크게 명심해야할 점은 두가지가 있다.
- thunk 내 action dispatch 불필요 및 action type 이름 자동 지정 (pending, fulfilled, rejected)
- action에 대한 reducer를 extraReducers에 정의
// userSlice.js
const { createSlice } = require('@reduxjs/toolkit');
const { createAsyncThunk } = require('@reduxjs/toolkit');
const axios = require('axios');
//initial state
const initialState = {
loading: false,
users: [],
error: '',
};
//thunk
const fetchUsers = createAsyncThunk('users/fetchUsers', () => {
return axios.get('https://jsonplaceholder.typicode.com/users').then((res) => {
return res.data.map((user) => user.id);
});
});
//reducer
// redux thunk 내에서 지정된 type 이름의 action이 자동 dispatch => pending, fulfilled, rejected
const userSlice = createSlice({
name: 'user',
initialState,
extraReducers: (builder) => {
builder.addCase(fetchUsers.pending, (state) => {
state.loading = true;
});
builder.addCase(fetchUsers.fulfilled, (state, action) => {
state.loading = false;
state.users = action.payload;
state.error = '';
});
builder.addCase(fetchUsers.rejected, (state, action) => {
state.loading = false;
state.users = [];
state.error = action.error.message;
});
},
});
module.exports = userSlice.reducer;
module.exports.fetchUsers = fetchUsers;
//index.js
const { configureStore } = require('@reduxjs/toolkit');
const userReducer = require('./userSlice');
const { fetchUsers } = require('./userSlice');
const store = configureStore({
reducer: {
user: userReducer,
},
});
store.subscribe(() => {
console.log(store.getState());
});
store.dispatch(fetchUsers());
'React' 카테고리의 다른 글
Redux toolkit - React (hook)+ Typescript 적용 (0) | 2022.05.16 |
---|---|
Redux toolkit - extraReducers(1) - module (0) | 2022.05.15 |
Redux toolkit - Redux toolkit 기본 (0) | 2022.05.15 |
Redux toolkit - redux 기본 (0) | 2022.05.15 |
blog 만들기 - husky v7, lint-staged, eslint, prettier (0) | 2022.04.12 |