TIL 2023.07.06

jomok·2023년 7월 6일
0
post-thumbnail

오늘 공부 계획 및 공부한 내용📝

  • 리액트 심화 강의 시청 ㅇ

Redux 미들웨어

리덕스에서 dispatch를 하면 action 이 리듀서로 전달되고, 리듀서는 새로운 state를 반환. '미들웨어'를 사용하면 이 과정 사이에 하고 싶은 작업들을 넣어 추가로 할 수 있음.

리덕스 thunk란,

리덕스에서 많이 사용하고 있는 미들웨어 중 하나. thunk를 사용하면 dispatch를 할 때 객체가 아닌 함수를 dispatch 할 수 있게 해줌.
즉, dispatch(객체) 가 아니라 dispatch(함수)를 할 수 있음.

그래서 중간에 하고 싶은 작업을 함수를 통해 넣을 수 있고, 그것을 중간에 실행할 수 있음.


🤔 dispatch(객체) vs dispatch(함수)

1) 객체를 디스패치하는 경우:

const increment = () => {
  return {
    type: 'INCREMENT',
  };
};

dispatch(increment());

액션 생성자 함수 increment()의 결과로 나오는 건 단순히 액션 객체
그 객체를 dispatch
액션 객체 { type: 'INCREMENT' }가 생성되어 리듀서 함수로 전달해 상태 업데이트 요청


2) 함수를 디스패치하는 경우 (Redux Thunk 사용)

const incrementAsync = () => {
  return (dispatch) => {
    setTimeout(() => {
      dispatch(increment());
    }, 1000);
  };
};

dispatch(incrementAsync());

dispatch(incrementAsync())를 호출하면, Redux Thunk는 함수를 인식하고 해당 함수 실행.
incrementAsync 함수 내부의 비동기 작업인 setTimeout이 실행되고 1초 후에 dispatch(increment())가 호출


예시1)

액션에 대한 타입과 액션 생성자 함수

const FETCH_DATA_REQUEST = 'FETCH_DATA_REQUEST';
const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS';
const FETCH_DATA_FAILURE = 'FETCH_DATA_FAILURE';

const fetchDataRequest = () => ({ type: FETCH_DATA_REQUEST });
const fetchDataSuccess = (data) => ({ type: FETCH_DATA_SUCCESS, payload: data });
const fetchDataFailure = (error) => ({ type: FETCH_DATA_FAILURE, payload: error });

비동기 작업을 처리하는 Redux Thunk 함수

const fetchData = () => {
  return async (dispatch) => {
    dispatch(fetchDataRequest());

    try {
      const response = await fetch('https://api.example.com/data');
      const data = await response.json();
      dispatch(fetchDataSuccess(data));
    } catch (error) {
      dispatch(fetchDataFailure(error.message));
    }
  };
};

fetchData 함수는 Redux Thunk함수로써, 비동기 작업을 처리할 때는 '액션 생성자 함수'를 호출하여 액션 객체를 반환하고, 이를 'dispatch 함수'를 통해 Redux 스토어에 디스패치.

--> 비동기 함수는 다른 작업이 진행될 때 동시에 다른 작업으로서 진행될 수 있는 함수, Redux Thunk를 사용하여 비동기 함수를 구현할 수 있음.

--> 액션 생성자 함수가 아닌, 액션 생성자 함수를 호출하여 반환된 액션 객체를 디스패치하는 방식으로 비동기 작업 처리. 이를 통해 상태를 업데이트하고 비동기 동작을 관리.

fetchData 함수 내에서 액션 생성자 함수를 호출하여 액션 객체를 반환하고 디스패치함으로써, 비동기 작업의 시작, 진행, 완료, 실패에 대한 상태 업데이트. 이를 통해 UI 상태를 업데이트하거나 사용자에게 정보를 전달하는 등의 처리를 할 수 있음.


예시2)

// 인자--> 컴포넌트에서 넘어온 payload, thunkAPI
export const __addTodo = createAsyncThunk(
  "addTodos",

  async (payload, thunkAPI) => {
    try {
      //서버에 새로운 데이터 보내줌
      await axios.post("http://localhost:3001/todos", payload);
      return thunkAPI.fulfillWithValue(payload);
    } catch (error) {
      console.log("error", error);
      return thunkAPI.rejectWithValue(error);
    }
  }
);

Redux Toolkit의 createAsyncThunk 함수를 사용하여 비동기 작업을 처리하는 Thunk 함수인 __addTodo를 생성.
"addTodos"라는 액션 타입과 비동기 작업 함수 정의.

비동기 작업 함수는 async 키워드 사용.
이 함수는 두 개의 인자인 payloadthunkAPI 필요함.
payload는 필요한 데이터나 파라미터를 전달하기 위한 값이고 thunkAPI는 Thunk 내부에서 Redux Toolkit이 제공하는 유틸리티 함수를 사용하기 위한 인자.

비동기 작업 함수 내부에서는 axios를 사용하여 해당 주소로 POST 요청을 보내고 payload를 서버에 전송(여기 payload 가 newTodo).
await 키워드를 사용하여 POST 요청이 완료될 때까지 기다림.

요청이 성공적으로 완료되면,
thunkAPI.fulfillWithValue(payload) 호출하여 액션의 페이로드로 전달된 payload를 반환. 이를 통해 액션 객체가 생성되고 리듀서에서 해당 액션을 처리하여 상태를 업데이트.

요청이 실패하면,
catch 블록으로 이동하여 error 변수에 에러를 저장하고, thunkAPI.rejectWithValue(error)를 호출하여 액션의 페이로드로 에러 전달.


문제🧐 / 해결과정⚒️

🤔 예시2는 createAsyncThunk 함수를 써서 thunk함수인지 확실히 알겠는데 예시1은 thunk함수인지 아닌지 어떻게 아는 거지?

📌 Redux Thunk를 사용하는 경우, dispatch 함수를 인자로 받는 함수를 리턴하는 형태로 작성한다. 따라서 fetchData 함수는 async (dispatch) => { ... }와 같은 형태로 되어 있으니 Redux Thunk 함수임.

결론 : 꼭 Thunk가 있어야 Thunk함수가 되는 것이 아님..

const fetchData = () => {
  return async (dispatch) => {
    dispatch(fetchDataRequest());

    try {
      const response = await fetch('https://api.example.com/data');
      const data = await response.json();
      dispatch(fetchDataSuccess(data));
    } catch (error) {
      dispatch(fetchDataFailure(error.message));
    }
  };
};

try-catch 문

try 블록
비동기 작업인 fetch를 호출하고 그 결과를 response 변수에 저장. await 키워드는 fetch 함수가 Promise를 반환하므로, 해당 Promise가 처리될 때까지 기다림.

catch 블록
블록 내부의 코드가 실행되다가 예외가 발생하면 코드 실행은 중단되고 catch 블록으로 이동.
해당 예외를 가리키는 에러 객체가 catch 블록의 인자로 전달되고 catch 블록 내부에서 예외에 대한 추가적인 처리가 진행됨.

0개의 댓글