2023년 03월 2주차 Week I Learned.

Dongchan Alex Kim·2023년 3월 12일
0

Week I Learned

목록 보기
5/14
post-thumbnail

이번 WIL은 각 항목별로 목적성에 대해서 조금 정리해보려고 한다.
대상은 아마도

  • Redux ToolKit(RTK)
  • json-server
  • axios
  • interceptor
  • Thunk

이 정도로 될꺼 같다.


Redux ToolKit (RTK)

RTK를 사용하는 이유에 대해서 한 번 짚어보자.

우리가 리덕스를 왜 쓸까?
리덕스는 무엇을 위해 쓰는것일까?
리덕스는 전역적으로 무언가를 쓰고 싶을때, 한꺼번에 관리할 수 있는 생태계를 만들어준다.
즉, 상태 값을 컴포넌트에 종속시키지 않고, 상태 관리를 컴포넌트의 밖에서 관리한다는 점에서
유지 보수에 매우 용이하다고 볼 수 있다.

컴포넌트가 스토어에 구독을 하면 구독을 하는 과정에서 특정 함수가 스토어에 전달됩니다.
그 후 스토어의 상태 값에 변동이 생기면 전달받았던 함수를 호출해주는 일련의 과정을 리덕스가 맡아준다는 것이다.

이렇게 좋은 리덕스가 있는데 RTK를 굳이 쓰는 이유는 또 무엇일까?
내가 느끼기에 가장 큰 이유는
아주 작은 기능이라도 리덕스로 구현하는 순간 몇 개의 파일들을 "필수로" 만들어야 한다는 점이다.
보일러 플레이트라고 불리는데,
리덕스를 구현하기 위해 필수적으로 구현해야하는 몇가지 파일들과 코드들을 준비해야하는 점이 번거롭다.

더 나아가,
리덕스에서 Reducer, 액션타입, 액션 크레에이트함수, initialState를
하나의 함수(createSlice함수)로 편하게 만들 수 있는 점이 RTK의 장점이 되시겠다.

Json-Server

$ yarn add json-server

$ yarn json-server --watch db.json --port 3001

json-server란,
아주 간단한 DB와 API 서버를 생성해주는 패키지라고 할 수 있다.
json-server를 사용하는 이유는 BE에서 실제 DB와 API Server가 구축될 때까지
FE개발에 임시적으로 사용할 mock data를 생성하기 위함이다.

그치만,
이 서버를 실제 서비스하는데는 적절하지 않기 때문에
테스트 또는 mock data용도로만 사용해야한다.

Axios

$ yarn add axios

http를 이용해서 서버와 통신하기 위해 사용하는 패키지이다.
API 서버는 우리가 만든 json-server를 사용한다.
배포는 하지 않아도 되고 한 프로젝트 내에서 다른 서버넘버로 가동시켜 사용한다.

axios를 사용해서 서버로부터 데이터를 요청하는 명령어는 기본적으로 4가지가 있고,
이는 get, delete, post, patch가 되겠다.

  • get
// 비동기처리를 해야하므로 async/await 구문을 통해서 처리.
const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:3001/todos");
};
  • post
const onSubmitHandler = async(todo) => {
	await axios.post("http://localhost:3001/todos", todo);
  };
  • delete
const onClickDeleteButtonHandler = (todoId) => {
   axios.delete(`http://localhost:3001/todos/${todoId}`);
};
  • patch
const onClickEditButtonHandler = (todoId, edit) => {
   axios.patch(`http://localhost:3001/todos/${todoId}`, edit);
};

Interceptor

axios interceptor는 다음 두 상황에서 흐름을 가로채서 어떠한 코드 상의 관여를 한다.

(1) 요청(request)이 처리되기 전( = http request가 서버에 전달되기 전)
(2) 응답(response)의 then(=성공) 또는 catch(=실패)가 처리되기 전

  • 요청 헤더 추가
  • 인증 관리
  • 로그 관련 로직 삽입
  • 에러 핸들링

Thunk

Thunk는 리덕스의 dispatch와 action이 리듀서로 전달되는 과정 사이에서 Thunk라는 미들웨어를 사용하여
하고 싶은 작업들을 넣어서 하는 용도라고 생각하면 되겠다.
즉, 액션이 리듀서로 전달되기전에 중간에 어떤 작업을 더 할 수있다.

리덕스 툴킷에서 Thunk 함수를 생성할 때는 createAsyncThunk 를 이용한다.

export const __addNumber = createAsyncThunk(
	// 첫번째 인자 : action value
  "addNumber", 
	// 두번째 인자 : 콜백함수 
  (payload, thunkAPI) => {
    setTimeout(() => {
      thunkAPI.dispatch(addNumber(payload));
    }, 3000);
  }
);

밑의 예시는 Thunk로 서버에서 데이터 가져오는 상황이다.

export const __getTodos = createAsyncThunk(
  //첫번쨰 인자 : action value
  "todos/getTodos",
  //두번째 인자 : 콜백
  async (payload, thunkAPI) => {
    try {
      const data = await axios.get("http://localhost:3001/todos");
      return thunkAPI.fulfillWithValue(data.data); // 성공
    } catch (error) {
      return thunkAPI.rejectWithValue(error); // 실패
    }
  }
);

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에 넣습니다.
    },
  },
});

export const {} = todosSlice.actions;
export default todosSlice.reducer;

axios get()함수는 promise를 반환하기 때문에, fulfilled 또는 rejected된 것을 처리하기 위해 async/await를 추가한 것이다.

thunk로 실행되는 것들은 메인 함수가 아닌 기타 Reducer로직을 구현할 때 extrareducers를 사용하고, 보통 thunk 함수를 사용할 때 extraReducers를 사용한다.
fulfilledwithvalue API가 실행되면, [ __getTodos.fulfilled ] 로 디스패치 된다.
그래서 state와 action을 받고, action객체에는 type과 payload가 찍히는 것이다.

각 상태 값을 true/false 상태로 정한 부분이기 때문에 이를 이용해서
상태에 따른 화면 구성을 진행할 수 있겠다.

profile
Disciplined, Be systemic

0개의 댓글