[redux] 리덕스 툴킷

리덕스 툴킷

스토어 생성 및 주입

import { configureStore } from '@reduxjs/toolkit';
import userReducer from './reducerA';
import postReducer from './reducerB';

const reducer = { 
	user : userReducer,
	post:  postReducer,
}
 
// 스토어 생성 및 미들웨어 설정
export default configureStore({ 
	reducer,
	middleware : (getDefaultMiddleware) =>
		getDefaultMiddleware()
  			.concat(logger)
			.concat(otherMiddleware),
}); 
import store from 'store/index.js';
import { Provider } from 'react-redux';
// 스토어 주입
ReactDOM.render(
		<Provider store={store} >
			<App />
		</Provider>
	),
	document.getElementById('root');
)

Slice

redux toolkit에서 slice는 리듀서와 action creator 등의 기능들을 제공해주는 객체이다.

import { createSlice } from '@reduxjs/toolkit';

export const counterSlice = createSlice({
	name: 'counter',
	initialState: {
		value: 0,
	},
	reducers : {
		increment: state =>{ 
			state.value += 1;
		},
		incrementByAmount: (state, action) =>{
			state.value += action,payload;
		}
	}
})

export const { increment, incrementByAmount }
 = counterSlice.actions;
export default counterSlice.reducer;

export const incrementAsync = createAsyncThunk('', 
	async () => {
		const response = await fakeAPI.get('/');
		return response.amount;
	}); 

Action

Action은 일반 plain object인데, 이 액션을 디스패치하기 위해서는 아래를 모두 작성해주어야 했다.

createSlice() 함수는 reducers 필드에서 작성해준 리듀서 함수와 같은 이름의 액션 생성자 함수를 만들어준다.

// export const {increment, incrementByAmount }
//  	= counterSlice.actions;

import { increment } from './counter'; 

dispatch(increment());

CreateAsyncThunk

해당 함수를 사용하면, 아래와 같은 액션을 별도로 생성할 필요가 없이, 자동으로 만들어준다.

리덕스 툴킷의 도움없이 작성된 비동기 함수의 예.

// 이전의 thunk 함수 예
const fetchStart = () => {
	type: 'post/start'
}
const fetchSuccess = () => {
	type: 'post/start'
}
const fetchFailure = () => {
	type: 'post/start'
}
const fetchPosts = (id) => async dispatch => {
	dispatch(fetchStart())
	try {
		const res = await exampleAPI.get('/');
		dispatch(fetchSuccess());
	} catch(err) {
		dispatch(fetchFailure());
	}	
}

리덕스 툴킷을 적용하면?

createAsyncThunk 함수를 사용하면, 자동으로

export const fetchPosts = createAsyncThunk('posts/fetchPosts', 
	async () =>{ 
		const res = await exmpleAPI.get('/');
		return res.data;
	}
);

하지만, createSlice 함수로 만들어진 객체는 결국에, reducers에 정의되어 있는 함수들에 대한 액션 디스패치에 응답하게 된다.

createAsyncThunk 함수의 경우에는 리듀서가 아니라 별개의 영영에 함수를 정의하여서 export 한 것이기 때문에, 이를 받아줄 별도의 영역이 필요한데 이것이 바로 extraReducers 이다.

const postReducers = createSlice({
	name: 'post',
	initialState,
	reducers : {
		// ...
	},
	extraReucers: {
	  [fetchPost.pending]: (state, action ) =>{ {
		// ...
	  },
    [fetchPost.fulfilled]: (state, action ) =>{ {
		// ...
	  },
    [fetchPost.rejected]: (state, action ) =>{ {
		// ...
	  },
	} 
})

#리덕스/리덕스툴킷# #Cheat-Sheet