redux-toolkit이란
react-redux의 설정/불변성 유지/반복되는 코드/미들웨어 설치 등 많은 불편함을 해소해준다
기존의 react-redux를 만드는 방식
createstore, initialState, reducer를 만듬
const initialState = {value : 0}
function reducer((state = initialState,action)=>{
if(action.type === "up") {
return {
...state,
value : state.value + action.step}
}
return state
})
const store = createStore(reducer)
App에 Provider store={store}을 감싸기
//모든 전역관리 라이브러리를 App에 provider를 감쌈
button을 만들어 onclick=>{()=>useDispatch({type:"up",step:2})}
redux-toolkit은 createSlice라고 redcuer를 전체로 사용하지 않고 액션 각각의 reducer 들을 만들어 마지막에 하나의 store로 머지한다.
사용예시)
const upActuon = createSlice({
name:"upHandler",
initialState : {value : 0}
// 각 속성마다 initialState 하나씩 (한번에 몰아서 안하고 필요한 것마다 하나씩)
// ↓ 각 속성 마다 개별 reducer 행동 창고 라고보면됨
reducers:{
up:(state,action) => {
//up 이라는 행위 밑에 다른행위로 함수를 또 만들면 다른 행위가 됨
//initialState 원본관리 안해줘도됨
// 여기 action안에는 payload 가 있음
state.value = state.value + action.payload
// return 되는 행위
}
}
})
const store = configureStore ({
// 각각의 슬라이스들에 대한 통합 reducer (여기 머지함)
reducer : {
작명 : upAction.reducer // createSlice를 담고 있는 변수명
// 이 작명은 slice.name 과 겹치면 안됨
}
})
toolkit에서 useSelector 쓰는법
const selector = useSelector(state => state.작명.value)
//원래는 state.counter 라고 했다면 state.counter.value로 한 단계 더 거쳐야함
// 작명은 configuStore에 작명한 이름 인 듯
dispatch 하는법
button onclick= {()=>{
useDispatch(사용 할 createSlice 변수명.actions.up(2))
}}
//action"s"와 paylaod는 약속
※ dispatch(슬라이스,actions.행동(payload))
코드 실적용
export const store = configureStore({
reducer: {
todo: todoReducer,
},
});
------------------------------------------------------
import { createSlice } from "@reduxjs/toolkit";
type todoSliceType = {
currentId: number;
todos: [
{
id: number;
text: string;
}
];
};
const todoSlice = createSlice({
name: "todo",
initialState: {
currentId: 0,
todos: [{ id: 0, text: "" }],
} as todoSliceType,
reducers: {
addTodo: (state, action) => {
const obj = {
id: state.currentId++,
text: action.payload.trim(),
state: "todo", // 얘는 status라네
};
state.todos.push(obj);
},
},
});
export default todoSlice.reducer;
// store의 configureStore.reducer에 머지를 위해 todoSlice.reducer이라고 해줌
dispatch 실사례
export const { addTodo } = todoSlice.actions;
import { addTodo } from "../reducer/slices/todoSlice";
dispatch(addTodo(currentValue));
Redux Toolkit의 비동기 처리
Redux Toolkit은 Thunk 미들웨어를 내장하고 있어 비동기 작업을 쉽게 처리할 수 있다.
함수실행
button onclick={()=>{
dispatch(asyncUpFetch())
}}
함수 실행 순서
dispatch(asyncUpFetch) >>> createSlice >>> pending/fulfiled/rejected를 선별해서 return
비동기 작업을 할 땐 createAsyncThunk 라는 함수를 만들어서 처리한다.
const asyncUpFetch = createAsyncThunk(
'counterSlice/asyncUpFatch', // counterSlice안의 asyncUpFetch를 실행한다는 뜻
async () =>{
const response = await fetch("주소")
const data = await response.json();
return data.value
}
)
//변수의 작명은 마음대로
CreateSlice 만들기
const counterSlice = createSlice({
name:"작명"
initialState:{
value:number:0,
상태:string:"첫로딩"
},
extraReducers : (builder) =>{
builder.addCase(asyncUpFetch.pending, (state,action)=>{
//asyncUpFetch엔 비동기함수
state.value = "값"
state.status : "로딩"
})
// 도는중 ↑
builder.addCase(asyncUpFetch.fulfilled, (state,action)=>{
//asyncUpFetch엔 비동기함수
state.value = action.payload
state.status = "성공"
})
//성공값↑
builder.addCase(asyncUpFetch .rejected, (state,action)=>{
//asyncUpFetch엔 비동기함수
state.value = "값"
state.status = "실패"
})
//실패값 ↑
}
})
toolkit의 비동기처리는 3가지 상태가 존재한다.
pending : 시작
fulfilled : 성공
rejected : 실패
이는 createSlice에 이렇게 분기로 넣어준다.
extraReducers : (builder) =>{
builder.addCase(asyncUpFetch.pending, (state,action)=>{
//asyncUpFetch엔 비동기함수
state.value = "값"
state.status : "로딩"
})
// 도는중 ↑
builder.addCase(asyncUpFetch.fulfilled, (state,action)=>{
//asyncUpFetch엔 비동기함수
state.value = action.payload
state.status = "성공"
})
//성공값↑
builder.addCase(asyncUpFetch .rejected, (state,action)=>{
//asyncUpFetch엔 비동기함수
state.value = "값"
state.status = "실패"
})
//실패값 ↑
}
비동기 함수가 에러일 때 화면 노출 팁