React (1) - redux-saga

2022. 4. 3. 13:17front-end/React

728x90

redux-thunk 대신 redux-saga 를 사용하는 이유

thunk 는 dispatch 를 여러번 불러오는 기능만 가지고 있다.

 

npm i redux-saga
npm i next-redux-saga

redux-saga

액션을 모니터링하고 있다가, 특정 액션이 발생하면 이에 따라 특정 작업을 하는 방식으로 사용합니다.

여기서 특정 작업이란, 특장 자바스크립트를 실행하는 것 일수도 있고, 다른 액션을 디스패치 하는 것 일수도 있고, 현재 상태를 불러오는 것 일수도 있습니다.

 

redux-saga는 redux-thunk로 못하는 다양한 작업들을 처리 할 수 있습니다. 예를 들자면..

  1. 비동기 작업을 할 때 기존 요청을 취소 처리 할 수 있습니다.
  2. 특정 액션이 발생했을 때 이에 따라 다른 액션이 디스패치되게끔 하거나, 자바스크립트 코드를 실행 할 수 있습니다.
  3. 웹소켓을 사용하는 경우 Channel 이라는 기능을 사용하여 더욱 효율적으로 코드를 관리 할 수 있습니다 (참고)
  4. API 요청이 실패했을 때 재 요청하는 작업을 할 수 있습니다.
  5. delay 를 제공합니다.
  6. 두번 클릭 했을 경우에 마지막 한번의 이벤트만 실행됩니다.

Generator 함수

const gen = function*(){
    console.log(1)
    yield;
    console.log(2)
    yield;
    console.log(3)
    yield(4);
}
const generator = gen();
generator.next();
{value: undefined, done: true} // done이 true가 될 때 까지 리턴

 

Effect

yield takeLatest('ADD_POST_REQUEST',addPost);
//take 를 사용하게 되면 한번 사용하고 끝
//takeLatest 클릭을 실수로 두번 했을 경우
//동시에 로딩중일 경우에만 앞에꺼는 실행하지 않고 마지막꺼 실행
//요청은 하되, 응답만 취소하는 것!!!! 백엔드에는 데이터가 두개 저장되어있을 수 있다.

yield throttle('ADD_POST_REQUEST',addPost,2000);
//2초 안에 몇 번 실행 되도 한번만 실행된다.throttle('??_REQUEST',addPost,2000);
  • 쓰로틀링: 마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 것
  • 스크롤을 올리거나 내릴 때 scroll 이벤트가 매우 많이 발생합니다.
    scroll 이벤트가 발생할 때 뭔가 복잡한 작업을 하도록 설정했다면 매우 빈번하게 실행되기 때문에 엄청 렉이 걸릴 것입니다. 그럴 때 쓰로틀링을 걸어줍니다. 몇 초에 한 번, 또는 몇 밀리초에 한 번씩만 실행되게 제한을 두는 것이죠.
var timer;
document.querySelector('#input').addEventListener('input', function (e) {
  if (!timer) {
    timer = setTimeout(function() {
      timer = null;
      console.log('여기에 ajax 요청', e.target.value);
    }, 200);
  }
});
  • 디바운싱: 연이어 호출되는 함수들 중 마지막 함수(또는 제일 처음)만 호출하도록 하는 것
  • 보통 사람들은 타자를 연달아칩니다. 중간에 잠시 생각하느라 몇 초 쉴 수는 있겠지만 대부분 한번에 검색어를 입력합니다. 따라서 입력이 다 끝난 후에 요청을 보내면 됩니다. 즉 타자를 칠 때(input 이벤트 발생)마다 타이머를 설정합니다. 200ms동안 입력이 없으면 입력이 끝난 것으로 칩니다(시간은 적당히 설정하면 됩니다). 200ms 이전에 타자 입력이 발생하면 이전 타이머는 취소하고 새로운 타이머를 다시 설정하는 겁니다.
var timer;
document.querySelector('#input').addEventListener('input', function(e) {
  if (timer) {
    clearTimeout(timer);
  }
  timer = setTimeout(function() {
    console.log('여기에 ajax 요청', e.target.value);
  }, 200);
});
728x90