React useReducer - 컴포넌트 재사용

YongWan·2023년 3월 14일
0

React Basic

목록 보기
7/10

개념

어떤 기능을 다른 컴포넌트에서도 재사용 하기 위해 useReducer를 사용한다.

// state: 현재의 상태
// dispatch: useReducer를 호출하게 되면 useReducer가 reducer를 호출하면서 state와 action을 파라미터로 전달
// reducer: 상태를 변경해주기 위해 불러오는 글로벌 함수
// initialState: 초기값
const [state, dispatch] = useReducer(reducer, initialState);

예제

할일을 변경, 추가, 삭제 할 수 있는 로직이다.

useState 사용

// Todo.jsx
import { useState } from "react";
import './Todo.css'

export default function Todo() {
  const [items, setItems] = useState(itemList);

  const handleUpdate = () => {
    const prev_cont = prompt('변경할 할일 입력');
    const cont = prompt('변경할 할일 입력');

    setItems(prev => prev.map(elm => {
      if(elm.cont === prev_cont) return ({...elm ,cont: cont});
      return elm
    }))
  }
  const handleAdd = () => {
    const cont = prompt('추가 할 할일 입력');
    
    setItems(prev => {
      return [...prev, {cont}]
    })

  }
  const handleRemove = () => {
    const cont = prompt('삭제 할 할일 입력');

    setItems(prev => prev.filter(elm => elm.cont !== cont));
  }

  return (
    <div className="container">
      <ul>
        {items.map((elm, idx) => 
          <li key={idx}>{elm.cont}</li>
        )}
      </ul>
      <div className="btn_box">
      <button onClick={handleUpdate}>할일 변경</button>
        <button onClick={handleAdd}>할일 추가</button>
        <button onClick={handleRemove}>할일 삭제</button>
      </div>
    </div>
  )
}

const itemList = [
  {
    id: '1',
    cont: '축구'
  },
  {
    id: '2',
    cont: '농부'
  },
  {
    id: '3',
    cont: '배구'
  }
]

useReducer 사용

// Todo.jsx
import { useReducer } from "react";
import reducer from "./reducer/reducer";
import './Todo.css'

export default function Todo() {
  // useReducer은 다른 컴포넌트에서의 재사용성을 위해 사용한다. 글로벌한 기능
  const [items, dispatch] = useReducer(reducer, itemList);

  const handleUpdate = () => {
    const prev_cont = prompt('변경할 할일 입력');
    const cont = prompt('변경할 할일 입력');

    // useReducer를 호출하면서 action 객체를 전달해 줄 수 있다.
    dispatch({type: 'update', prev_cont, cont});
  }
  const handleAdd = () => {
    const cont = prompt('추가 할 할일 입력');
    
    dispatch({type: 'add', cont})
  }
  const handleRemove = () => {
    const cont = prompt('삭제 할 할일 입력');

    dispatch({type: 'remove', cont});
  }

  return (
    <div className="container">
      <ul>
        {items.map((elm, idx) => 
          <li key={idx}>{elm.cont}</li>
        )}
      </ul>
      <div className="btn_box">
      <button onClick={handleUpdate}>할일 변경</button>
        <button onClick={handleAdd}>할일 추가</button>
        <button onClick={handleRemove}>할일 삭제</button>
      </div>
    </div>
  )
}

const itemList = [
  {
    id: '1',
    cont: '축구'
  },
  {
    id: '2',
    cont: '농부'
  },
  {
    id: '3',
    cont: '배구'
  }
]
// reducer.jsx(상태를 변경해주는 함수)
// 기존의 state = list, 추가되는 action 객체를 파라미터로 전달 받는다.
export default function reducer(list, action) {
  switch(action.type) {
    case 'update': {
      // const prev_cont = action.prev_cont;
      // const cont = action.cont
      const {prev_cont, cont} = action;
      list.map(elm => {
        if(elm.cont === prev_cont) {
          return elm.cont = cont
        };
      })
      return [...list]
    }
    case 'add': {
      const cont = action.cont;
      return [...list, {id: 5 ,cont: cont}]
    }
    case 'remove': {
      const cont = action.cont;
      return list.filter(elm => elm.cont !== cont)
    }
    default: {
      throw Error('알수없음')
    }
  }
}

0개의 댓글