zeroCho react-NodeBird 3강

오늘 공부

React-redux

  • 기존의 connect 함수를 써서 HOC로 만들어 사용하는 방식

  • react-redux 7.1.0 버전 이후 부터 사용 가능한 리덕스훅 방식

         const dispatch = useDispatch();
         dispatch({type:'', data:{}}
    
         const selectedReducer = useSelector(state => state.reducer)
  • react state와 redux state는 같이 쓴다.
    redux state만 쓰면 reducer가 너무 복잡해지므로 간단한 form같은 state는 react state로 만드는 것이 좋다. 반면에, 서버와 통신 or 여러 컴포넌트가 같이 쓰는 state는 redux로 하는 것이 좋다.

리덕스 사가 살짝 맛만 보기

  • redux의 문제 : 각각의 state가 바뀌면 동기적으로 바뀌는 것 밖에 못함
    비동기적인 요청을 위해 리덕스의 기능을 확장할 필요가 있음(미들웨어 사용) redux-saga(대세), redux-chunk(쉬움, 기능약함), redux-observable(잘 안씀)
    ex) 서버로 요청을 보내는 작업을 할 수 없음(바로 실행되기 때문에)
    반면에, redux-saga는 액션이 실행되는지 대기하다가 액션이 실행되면 비동기 실행을 한다.

  • saga의 문법 : 제너레이트 함수 = 함수 실행을 중간에 멈출 수 있는 함수(보통 비동기 처리나 무한반복문을 이용하여 무한의 처리를 할 때 사용)

    1. (중간의 멈춤)
     function* generator () {
           console.log(a)
           yield;// 중단점, {value : null, done : false}
            console.log(b)
           yield 5; // 중단점, {value : 5, done : ture}
           console.log(c)
           yield* `12345` // 1->중단->2->중단->3->중단->4->중단->5
    
         yield take(action)
       // 해당 액션이 dispatch되면 제너레이터를 next하는 이펙트
           yield delay(2000);
           yield put(action0)
       // put은 redux의 dispatch와 같은 의미
       // 바로 윗줄 코드와 합쳐서 보면 action을 받으면 2초후에 action0을 자동으로 실행한다는 의미
    
           yield all([action1, action2, action3])
       // action 1, 2, 3중 하나가 dispatch되면 next하는 이펙트
     }
    
     const gen = generator();
     gen.next() // 제너리이터 함수 실행 -> yield에서 중단
     // 제너레이터 함수가 끝나서 클로즈드가 되기 전까지는 여러번 실행 가능
  1. (무한의처리)

    function* watchHello() {
     yield takeEvery(HELLO_SAGA, function*() {
       yield delay(1000)
       yield put({
         type:BYE_SAGA,
       })
     }
    
     yield takeLatest(HELLO_SAGA, function*(){
       // 동시에 여러 액션이 들어오면 마지막 액션만 처리한다.
       // 즉 HELLO_SAGA가 6번 동시에 들어오면 마지막 HELLO_SAGA 하나만 처리됨
     }
    }
    
    // 참고)
    function* watchHello2() {
      while (true) {
        yield take(HELLO_SAGA);
        // takeEvery와 같은 결과
      }
    }
    1. 함수실행 이펙트

      function* functionEffect() {
          yield call(watchHello())
        // 동기호출 (서버요청 보내고 응답 받을 때까지 기다림)
          yield fork(watchHello())
        // 비동기호출 (서버요청 보내고 성공여부 상관없이 계속 실행)
        }
      }
    2. 기타 이펙트
      race, cancel, select, throttle 등...

    3. 리덕스 사가 코딩 패턴

      function* loginAPI() {        
        // 서버에 요청을 보내는 부분
      }
      function* login() {
        try {
          yield call(loginAPI);
          yield put({
            type: LOG_IN_SUCCESS
          });
        } catch (e) {
          console.error(e);
          yield put({
            type: LOG_IN_FAILURE
          });
        }
      }
      // 3. 실제로 어떻게 동작할지 구현
      
      function* watchLogin() {
        yield takeLatest(LOG_IN_REQUEST, login);
      }
      // 2. takeEvery인지 takeLatest인지 결정
      
      export default function* userSaga() {
        yield all([fork(watchLogin)]);
      }
      // 1. 실행할 함수 선언

      실제로 실행할 함수 선언 -> takeEvery인지 takeLatest인지 결정 -> 실제로 어떻게 동작할지 구현

느낀점

  • 배울게 너무 많고 배운거 또 까먹고... 이래서 언제 프로젝트를 할 수 있을까 걱정된다.

내일 공부

  • 리덕스 사가 실습
  • NextJS 이론공부
  • zeroCho 4강