typesafe-actions 라이브러리 적용하기
리덕스 모듈을 굉장히 짧게 코드를 줄여줌
리덕스 모듈 구조
액션타입/ 액션생성함수/ 리듀서/상태타입
설치
npm install typesafe-actions
1. 액션 타입 변경
const INCREASE = "counter/INCREASE" as const → const INCREASE = "counter/INCREASE"
2. 액션 생성 함수
구문)
import { deprecated } from "typesafe-actions";
const {createStandardAction, createAction} = deprecated;
createStandardtAction(액션타입)<전달받은 값 타입>
createAction(액션타입)
action()함수는 액션객체를 만드는 함수
액션타입정의
구문 ex)
import { ActionType } from "typesafe-actions";
const actions = {increase, decrease};
파라미터와 payload값의 형태가 다를 때
파라미터를 기반으로 커스텀마이징 된 payload설정일때
음... 그러니깐 전달 받은 타입과 payload(전달받은)타입이 일치하는 경우
createStandartAction(액션타입)<전달받은 값 타입> 사용
전달받은 타입과 payload(전달 받은)타입이 다를 경우
createAction(액션타입) 사용
예시)
type-action 적용 전
export const addTodo = (text:string) => ({
type: ADD_TODO,
payload: {
id: nextId++,
text: text
}
})
export const toggleTodo = (id:number) => ({
type: TOGGLE_TODO,
payload: id
})
export const removeTodo = (id:number) => ({
type: REMOVE_TODO,
payload: id
})
type-action 적용 후
//2.액션 생성 함수
export const addTodo = createAction(ADD_TODO, action => (text:string)=>
action({
id: nextId++,
text: text
})
)
export const toggleTodo = createStandardAction(TOGGLE_TODO)<number>();
export const removeTodo = createStandardAction(REMOVE_TODO)<number>();
//액션타입정의
const actions = {addTodo, toggleTodo, removeTodo}
type TodoAction = ActionType<typeof actions>
3.리듀서 생성함수(todolist예시)
type-action 적용 전
function todos(state: TodoState= initialState, action:TodoAction){
switch(action.type){
case ADD_TODO:
return [
...state,
{
id: action.payload.id,
text: action.payload.text,
isDone: false
}
]
case TOGGLE_TODO:
//이전상태 배열을 순환하며 배열 요소의 id값과 action의 payload일치하는지
//값이 일치하면 요소의 isDone을 반전해서 리턴
//일치하지 않으면 배열요소 리턴
return state.map(todo=>todo.id === action.payload ?
{...todo, isDone: !todo.isDone}: todo);
case REMOVE_TODO:
return state.filter(todo=> todo.id !== action.payload)
default:
return state
}
}
export default todos;
구문)
createReducer<상태타입, 액션타입>(초기상태값, {
[액션타입1]:(state, action)=> 리턴값,
[액션타입2]:(state, {payload: id}) => 리턴값,
[액션타입3]:(state, {payload: id}) => 리턴값
})
type-action 적용 후
//3. 리듀서 함수 - state타입 action타입지정
const todos = createReducer<TodoState, TodoAction>(initialState, {
[ADD_TODO]: (state, action) =>
[...state, {...action.payload, isDone:false}],
[TOGGLE_TODO]: (state, {payload: id}) => state.map(todo=>todo.id === id ?
{...todo, isDone: !todo.isDone}: todo),
[REMOVE_TODO]: (state, {payload: id}) => state.filter(todo=> todo.id !== id)
})
export default todos;
모듈 전체 변경전
//1.액션타입
//type-action 적용전
const ADD_TODO = "todos/ADD_TODO" as const
const REMOVE_TODO = "todos/REMOVE_TODO" as const
const TOGGLE_TODO = "todos/TOGGLE_TODO" as const
//t새로운 항목 추가할때 사용할 id값
let nextId = 1;
//2.액션 생성 함수
export const addTodo = (text:string) => ({
type: ADD_TODO,
payload: {
id: nextId++,
text: text
}
})
export const toggleTodo = (id:number) => ({
type: TOGGLE_TODO,
payload: id
})
export const removeTodo = (id:number) => ({
type: REMOVE_TODO,
payload: id
})
//ReturnType<typeof addTodo> 특정함수의 리턴타입을 추론
type TodoAction = ReturnType<typeof addTodo>
| ReturnType<typeof removeTodo>
|ReturnType<typeof toggleTodo>
//상태에서 사용할 할일 항목의 타입정의
export type Todo ={
id: number;
text: string;
isDone: boolean;
}
//상태에 대한 타입
export type TodoState = Todo[]
// 초기상태 선언
const initialState: TodoState = [];
//3. 리듀서 함수 - state타입 action타입지정
//type-action 적용전
function todos(state: TodoState= initialState, action:TodoAction){
switch(action.type){
case ADD_TODO:
return [
...state,
{
id: action.payload.id,
text: action.payload.text,
isDone: false
}
]
case TOGGLE_TODO:
//이전상태 배열을 순환하며 배열 요소의 id값과 action의 payload일치하는지
//값이 일치하면 요소의 isDone을 반전해서 리턴
//일치하지 않으면 배열요소 리턴
return state.map(todo=>todo.id === action.payload ?
{...todo, isDone: !todo.isDone}: todo);
case REMOVE_TODO:
return state.filter(todo=> todo.id !== action.payload)
default:
return state
}
}
export default todos;
모듈 전체 변경후
//액션 생성, 액션 생성함수, 리듀서
import { ActionType, createReducer, deprecated } from "typesafe-actions";
const {createStandardAction, createAction} = deprecated;
//1.액션타입
const ADD_TODO = "todos/ADD_TODO"
const REMOVE_TODO = "todos/REMOVE_TODO"
const TOGGLE_TODO = "todos/TOGGLE_TODO"
//t새로운 항목 추가할때 사용할 id값
let nextId = 1;
//2.액션 생성 함수
export const addTodo = createAction(ADD_TODO, action => (text:string)=>
action({
id: nextId++,
text: text
})
)
export const toggleTodo = createStandardAction(TOGGLE_TODO)<number>();
export const removeTodo = createStandardAction(REMOVE_TODO)<number>();
const actions = {addTodo, toggleTodo, removeTodo}
type TodoAction = ActionType<typeof actions>
//상태에서 사용할 할일 항목의 타입정의
export type Todo ={
id: number;
text: string;
isDone: boolean;
}
//상태에 대한 타입
export type TodoState = Todo[]
// 초기상태 선언
const initialState: TodoState = [];
//3. 리듀서 함수 - state타입 action타입지정
const todos = createReducer<TodoState, TodoAction>(initialState, {
[ADD_TODO]: (state, action) =>
[...state, {...action.payload, isDone:false}],
[TOGGLE_TODO]: (state, {payload: id}) => state.map(todo=>todo.id === id ?
{...todo, isDone: !todo.isDone}: todo),
[REMOVE_TODO]: (state, {payload: id}) => state.filter(todo=> todo.id !== id)
})
export default todos;
다시 정리해보자면.....
typesafe-actions 라이브러리 적용하기
*리덕스 모듈을 좀더 간결하게 작성
액션타입, 액션생성함수, 리듀서 함수, 상태타입
1.액션타입
const INCREASE = "counter/INCREASE" as const
-=> const INCREASE = "counter/INCREASE" 바뀜
2. 액션생성함수
*액션타입에 type속성만 있는경우
createStandardAction(액션타입)();
*액션객체에 전달하는 속성이 있는 경우(payload 속성이 있는 경우)
1) 전달 받은 타입과 payload타입이 일치하는 경우
ex)
ToggleTodo(1) ---> dispatch({type: TOGGLE_TODO, payload: 1}) << 이 상황일 경우(payload 타입이 일치하는 경우)
createStandardAction(액션타입)<payload값 타입>
ADDTodo("리액트포톨만들기") ====> dispatch({type:ADD_TODO, payload: {id:2, text: "리액트포폴만들기"}})
2) 전달받은 타입과 payload타입이 다를 경우
createAction(액션타입, action => (text:string) =>
action({id: 2, text: text})
)
3. 액션 객체에 대한 타입
const actions = {액션생성함수1, 액션생성함수2...}
type TodoAction = ActionType<typeof action>
4. 리듀서
const todos = createReducer<액션타입, 액션타입>(상태초기값, {
[액션타입1]: (state, action) => 상태리턴,
[액션타입2]: (state, action) => 상태리턴
})
'typescript' 카테고리의 다른 글
[typescript] json-server라이브러리, react-typescript(styled-components) (2) | 2023.02.24 |
---|---|
[typescript]react-typescript(redux) (0) | 2023.02.24 |
[typescript] as & ReturnType (0) | 2023.02.24 |
[typescript] react-typscript(useReducer + contextAPI) (0) | 2023.02.24 |
[typescript] react-typscript(usereducer) (0) | 2023.02.24 |
댓글