한입크기 리액트 일기장13. 복잡한상태 관리 로직 분리 - useReducer

임하나·2023년 2월 13일
0

한입크기리액트

목록 보기
15/21

상태변화로직분리하기

useReducer

컴포넌트에서 상태변화 로직을 분리하자.

첫번째 count 기존의 사용했던 state
두번째 dispatch 상태를 변화시키는 action
reducer dispatch 상태변화함수를 처리하는 로직
1 count state의 초기값이다.


기존에 작성했던 useState는 주석처리를 해주고
useReducer를 작성해보자.

App.js

//const [data, setData] = useState([]);

useState대신 useReducer를 쓰는 이유는. 복잡한 상태변화를 로직을 컴포넌트 밖으로 분리하기 위해서다.

import { useCallback, useReducer, useState, useRef, useEffect, useMemo } from 'react';
const [data, dispatch] = useReducer(reducer, []);
const reducer = (state, action) => {
  switch(action.type){
    case 'INIT' : 
    case 'CREATE' :
    case 'REMOVE' :
    case 'EDIT':
    default :
    return state;
  }
}

case별로 추가해주자

INIT -> getData

const getData = async () => {
  const res = await fetch(
    "https://jsonplaceholder.typicode.com/comments"
  ).then((res) => res.json());

  const initData = res.slice(0,20).map((it)=>{
    return {
      author:it.email,
      content:it.body,
      emotion:Math.floor(Math.random()*5)+1,
      created_date : new Date().getTime(),
      id : dataId.current++
    }
  });
  dispatch({type:'INIT', data:initData});
  //setData(initData);
}
const reducer = (state, action) => {
  switch(action.type){
    case 'INIT' : {
      return action.data
    }
  }
}

CREATE -> onCreate

const onCreate = useCallback((author, content, emotion) => {
  dispatch({type:'CREATE', data:{author, content, emotion, id:dataId.current}});
  dataId.current += 1;
  //const created_date = new Date().getTime();
  // const newItem = {
  //   author,
  //   content,
  //   emotion,
  //   created_date,
  //   id : dataId.current
  // }

  //setData((data)=>[newItem, ...data]);
},[]);
case 'CREATE' :{
  const created_date = new Date().getTime();
  const newItem = {
    ...action.data,
    created_date
  }
  return [newItem, ...state];
}

REMOVE -> onRemove

const onRemove = useCallback((targetId) =>{
  dispatch({type:'REMOVE', targetId});
  //setData(data=>data.filter((it)=>it.id!==targetId));   
},[]);
case 'REMOVE' : {
  return state.filter((it)=>it.id!== action.targetId);
}

onEdit -> EDIT

 const onEdit = useCallback((targetId, newContent) => {
   dispatch({type:'EDIT', targetId, newContent})
   // setData((data)=>  
   //   data.map((it)=>
   //     it.id === targetId ? {...it, content:newContent} : it
   //   )
   // )
 },[])
case 'EDIT': {
      return state.map((it)=>it.id === action.targetId ? {...it, content:action.newContent} : it)
    }

0개의 댓글