티스토리 뷰

Redux

[Redux] Redux Thunk, Redux Toolkit

soobin Choi 2022. 12. 12. 04:12

[ Builder Callback 표기법 ]
redux toolkit - thunk 를 이용해서 비동기 작업을 처리하는 방법 by 생활코딩
- 전체 코드

const status = useSelector(state => {
	return state.counter.status;
});

const count = useSelector(state => {
	return state.counter.value;
});

<button onClick={() => {
	dispatch(asyncUpFetch());
}}>+ async thunk</button>
<div>{count} | {status}</div>

const asyncUpFetch = crateAsynckThunk(
	'counterSlice/asyncUpFetch',
    async() => {
    	const resp = await fetch('httpsL//~')
        const data = await resp.json();
        return data.value;
    }
)

const counterSlice = createSlice({
	name:'counterSlice',
    initialState{
    	value:0,
        status:'Welcome'
    },
    extraReducers:(builder)=>{
    	builder.addCase(asyncUpFetch.pending, (state,action) => {
        	state.status = 'Loading';
        })
    	builder.addCase(asyncUpFetch.fulfiled, (state,action) => {
        	state.value = action.payload;
            state.status = 'complete';
        })
        builder.addCase(asyncUpFetch.rejected, (state,action) => {
        	state.status = 'fail';
        })
    }
})


☆ createAsyncThunk는 비동기 작업을 처리하는 action을 만들어준다!

const asyncUpFetch = crateAsynckThunk(
	'counterSlice/asyncUpFetch',
    async() => {
    	const resp = await fetch('httpsL//~')
        const data = await resp.json();
        return data.value;
    }
)

1.

	'counterSlice/asyncUpFetch',

첫 번째 타입을 적은 것
2.

    async() => {
    	const resp = await fetch('httpsL//~')
        const data = await resp.json();
        return data.value;
    }

액션이 실행 됐을 때 처리되어야 하는 작업
: 서버에 접속 - 결과 가져오기 - 결과 리턴하기
두 번째 파라미터에 이 작업을 함수로서 전달함

✔️ action creator는 아래와 같이 3가지 상태를 갖습니다.
- action creator.pending는 대기상태를 의미합니다.
- action creator.fulfilled 는 완료 상태를 의미합니다.
- action creator.rejected는 오류 상태를 의미합니다.
*createAsyncThunk를 쓰면 자동으로 만들어지는 상수

📌 위의 세가지 상태 별로 reducer가 필요함. 이 reducer를 어디다 주나?

const counterSlice = createSlice({
	name:'counterSlice',
    initialState{
    	value:0,
        status:'Welcome'
    },
    extraReducers:(builder)=>{
    	builder.addCase(asyncUpFetch.pending, (state,action) => {
        	state.status = 'Loading';
        })
    	builder.addCase(asyncUpFetch.fulfiled, (state,action) => {
        	state.value = action.payload;
            state.status = 'complete';
        })
        builder.addCase(asyncUpFetch.rejected, (state,action) => {
        	state.status = 'fail';
        })
    }
})

createSlice 에서 extraReducers 의 builder.addCase()를 통해서 각 상태일 때 동작할 reducer를 두 번째 파라미터의 함수로 전달

✔️ thunk는 각각의 상태에 따른 reducer를 체계적으로 작성할 수 있도록 유도합니다.
thunk를 처리할 때는 extraReducers를 사용합니다.

동기적 액션에는 reducers를, 비동기적인 작업에는 extraReducers를 사용하는데,
reducers로 동기 작업을 할 때는 리덕스 툴킷이 action creator를 자동으로 만들어주는 반면
extraReducers로 비동기 작업을 할 때는 툴킷이 action creator를 자동으로 만들지 못한다.
그래서 비동기 작업을 할 때는 extraReducers 안에서 action creator를 정의해 준다.


[Map Object 표기법]

*생활코딩 강의 내용을 todoSlice.js 에 적용하면

// 완성된 Thunk 함수
export const __getTodos = createAsyncThunk(
  "todos/getTodos",
  async (payload, thunkAPI) => {
    try {
      const data = await axios.get("<http://localhost:3001/todos>");
      console.log(data);
    } catch (error) {
      console.log(error);
    }
  }
);

1.

 "todos/getTodos",

첫 번째 타입을 적은 것
2.

  async (payload, thunkAPI) => {
    try {
      const data = await axios.get("<http://localhost:3001/todos>");
      console.log(data);
    } catch (error) {
      console.log(error);
    }
  }

액션이 실행 됐을 때 처리되어야 하는 작업
: 서버에 접속 - 결과 가져오기 - 결과 리턴하기
두 번째 파라미터에 이 작업을 함수로서 전달함

📌 위의 세가지 상태 별로 reducer가 필요함. 이 reducer를 어디다 주나?

export const todosSlice = createSlice({
  name: "todos",
  initialState,
  reducers: {},
  extraReducers: {
    [__getTodos.pending]: (state) => {
      state.isLoading = true; // 네트워크 요청이 시작되면 로딩상태를 true로 변경합니다.
    },
    [__getTodos.fulfilled]: (state, action) => {
      state.isLoading = false; // 네트워크 요청이 끝났으니, false로 변경합니다.
      state.todos = action.payload; // Store에 있는 todos에 서버에서 가져온 todos를 넣습니다.
    },
    [__getTodos.rejected]: (state, action) => {
      state.isLoading = false; // 에러가 발생했지만, 네트워크 요청이 끝났으니, false로 변경합니다.
      state.error = action.payload; // catch 된 error 객체를 state.error에 넣습니다.
    },
  },


http://blog.hwahae.co.kr/all/tech/tech-tech/6946/

 

Redux Toolkit (리덕스 툴킷)은 정말 천덕꾸러기일까?

Redux Toolkit 최근 훅 기반의 API 지원이 가속화되고 React Query, SWR 등 강력한 데이터 패칭과 캐싱 라이브러리를 사용하면서 리덕스 사용이 줄어드는 방향으로 프론트엔드 기술 트렌드가 변화하고 있

blog.hwahae.co.kr

https://www.youtube.com/watch?v=K-3sBc2pUJ4&ab_channel=%EC%83%9D%ED%99%9C%EC%BD%94%EB%94%A9