React Todo with Saga

김승훈·2021년 2월 12일
0

React

목록 보기
4/14

Todo

todo 찾아보면 만들어보기 ~!목표

  • 리덕스 적용하여 상태관리
  • 리덕스 사가 붙이기

궁금점

리덕스와 리액트 contextAPI는 언제 사용하면 좋을까?

리액트 contextAPI는 컨포넌트의 통합 데이터를 관리하는 경우,

리덕스는 서버에서 가져온 데이터로 새로운 결과물을 만드는 경우

라고 하지만 잘모르겠다 !

useCallback 어떻게 사용해야할까 ~

 const onGoAuthMobilePage = React.useCallback(()=>{ //렌더링 최소화

    },[]) //배열 값 바뀌었을 때만 함수를 새로 생성(-> 비어있으면 렌더링 한번만)

이 배열에 넣어놓은 object의 상태가 변하지 않는 이상 리렌더링 되지 않는다.

React.useCallback(()=>{
	console.log(a)
    },[a])

리덕스를 적용하여 투두 만들기

redux 설치

$ npm i redux

$ npm i react-redux

리덕스 개발 툴 설치

redux-devtools

$ npm i -D redux-devtools

리덕스 3가지 규칙

하나의 애플리케이션 안에는 하나의 스토어가 있습니다.

상태는 읽기전용 입니다.

. 변화를 일으키는 함수, 리듀서는 순수한 함수여야 합니다.

순수한 함수, 라는 개념이 익숙하지 않으시죠. 다음 사항을 기억해주세요.

  • 리듀서 함수는 이전 상태와, 액션 객체를 파라미터로 받습니다.
  • 이전의 상태는 절대로 건들이지 않고, 변화를 일으킨 새로운 상태 객체를 만들어서 반환합니다.
  • 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결과값을 반환해야만 합니다.

리듀서는 모듈로 나누어서 만들고 index에서 combineReducers로 합치기

액션타입, 액션함수, 만들기

호출 할때 그 파일들 import 해 오기

액션함수 호출 useDispatch

스토어 상태 불러오기 useSelector

  1. 리덕스 적용
    리덕스만 적용 했을 떄는 dispatch로 액션함수만 연결해주면 되었다.
    1. dispath로 액션함수 실행 ⇒ 리턴값으로 type 과 data 전송
    2. 리듀서 실행 !

    ```jsx
    //액션함수
    export const addTodo = (data) => ({
      type:ADD_TODO,
      data
    })
    
    export const deleteTodo = (data) => ({
      type:DELETE_TODO,
      data
    })
    
    export const updateTodo = (data) => ({
      type:UPDATE_TODO,
      data
    })
    
    //실행
    const deleteTodoClick = useCallback(() => {
        dispatch(deleteTodo(todo.id))
      },[todo])
    //
    const reducer = (state = initalState, action) =>{
      switch(action.type){
        case ADD_TODO :
        return{
            ...state,
            todos:[action.data, ...state.todos]
          };
        case DELETE_TODO :
          return{
            ...state,
            todos:state.todos.filter((todo) => (todo.id !== action.data)),
          };
        case UPDATE_TODO : {
          return {
            ...state,
            todos:state.todos.map(todo => (
              todo.id === action.data
              ? {...todo, checked:!todo.checked}
              : todo
            ))
          };
        }
        default:
          return state;
      }
    };
    ```
  2. 리덕스 + 리덕스 사가 적용했을 때 ~!

    리덕스 + 리덕스 사가를 연결하였을 때는 액션타입을 요청 성공 실패로 나뉜다

    리듀서로 또한 3가지 타입으로 나뉜다. 그리고 요청만 리덕스로 하고 성공 실패는 리덕스사가로 실행한다.

    1. dispatch로 요청타입 액션함수 실행 ⇒리턴값으로 type data 전송
    2. 리듀서 실행 후 바로 리덕스 사가로 통해 fork로 함수실행 ⇒ put(dispatch)으로 성공or 실패 타입 리듀서 실행
    //함수 실행
    const deleteTodoClick = useCallback(() => {
        dispatch(deleteTodo(todo.id))
      },[todo])
    
    //액션함수
    export const addTodo = (data) => ({
      type:ADD_TODO_REQUEST,
      data
    })
    export const deleteTodo = (data) => ({
      type:DELETE_TODO_REQUEST,
      data
    })
    export const updateTodo = (data) => ({
      type:UPDATE_TODO_REQUEST,
      data
    })
    //리덕스 사가 함수
    3.
    function* addTodo(action){
      try {
        yield delay(100);
        yield put({
          type: ADD_TODO_SUCCESS,
          data: action.data,
        });
      } catch (error) {
        yield put({
          type: ADD_TODO_FAIL,
          data: action.data,
        });
      }
    }
    function* deleteTodo(action){
      try {
        yield delay(100);
        yield put({
          type: DELETE_TODO_SUCCESS,
          data: action.data,
        });
      } catch (error) {
        yield put({
          type: DELETE_TODO_FAIL,
          data: action.data,
        });
      }
    }
    function* updateTodo(action){
      try {
        yield delay(100);
        yield put({
          type: UPDATE_TODO_SUCCESS,
          data: action.data,
        });
      } catch (error) {
        yield put({
          type: UPDATE_TODO_FAIL,
          data: action.data,
        });
     }
    2.
    //리덕스 사가
    function* watchAddTodo(){
      yield takeLatest(ADD_TODO_REQUEST,addTodo);
    }
    function* watchDelteTodo(){
      yield takeLatest(DELETE_TODO_REQUEST,deleteTodo)
    }
    function* watchUpdateTodo(){
      yield takeLatest(UPDATE_TODO_REQUEST,updateTodo)
    }
    1.
    export default function* todoSaga(){
      yield all([
        fork(watchAddTodo),
        fork(watchDelteTodo),
        fork(watchUpdateTodo),
      ])
    }

0개의 댓글