[SeSAC Front-end] [React] useReducer 실습문제 풀기

Harimad·2022년 12월 6일
0

React

목록 보기
6/18
post-thumbnail

🌱 Intro

  • React에서 useState 대신 상태관리를 할 수 있는 useReducer를 이용한 실습문제를 풀어보겠습니다.
  • 실습 문제를 풀면서 useReducer를 어떻게 사용하는지 알아보겠습니다.😀
  • CSS styling은 본인의 취향에 맞게 적용하시면 됩니다. 없어도 무방합니다.

🌱 본론


🟢 문제 1

🟢 풀이

import React, { useReducer } from 'react'

const priceReducer = (state, action) => { // 1
  switch (action.type) {
    case 'HAMBURGER':
      return state + 4000
    case 'POTATO':
      return state + 3000
    case 'COKE':
      return state + 1000
    default:
      return state
  }
}

const App = () => {
  const [state, dispatch] = useReducer(priceReducer, 0) // 2

  const clickHamburger = () => { // 3
    dispatch({ type: 'HAMBURGER' })
  }
  const clickPotato = () => { // 4
    dispatch({ type: 'POTATO' })
  }
  const clickCoke = () => {
    dispatch({ type: 'COKE' })
  }
  return (
    <div>
      <h2>새도날드</h2>
      <h3>지불할 금액 : {state}</h3> // 5
      <button onClick={clickHamburger}>🍔</button>  // 6
      <button onClick={clickPotato}>🍟</button>
      <button onClick={clickCoke}>🥤</button>
    </div>
  )
}

export default App

① useReducer함수에 넣을 reducer 함수를 설정합니다.
② useReducer함수를 이용한 state를 초기화 합니다.
③ 클릭했을 때 dispatch 함수를 실행할 함수를 설정합니다.
④ 클릭했을 때 dispatch 함수를 실행할 함수를 설정합니다.
⑤ state 값을 브라우저에서 보여줍니다.
⑥ click 이벤트가 발생했을 때 해당 함수를 실행합니다.


🟡 문제 2

🟡 풀이

import React, { useReducer, useState } from 'react'

const accountReducer = (state, action) => { // 1
  switch (action.type) {
    case 'DEPOSIT':
      return state + Number(action.money)
    case 'WITHDRAW':
      return state - Number(action.money)
    default:
      return state
  }
}

const App = () => {
  const [state, dispatch] = useReducer(accountReducer, 0) // 2
  const [money, setMoney] = useState(0) // 3

  const clickDeposit = () => { // 4
    dispatch({ type: 'DEPOSIT', money: money }) 
  }
  const clickWithdraw = () => {
    dispatch({ type: 'WITHDRAW', money: money })
  }
  return (
    <div>
      <h2>금액을 입력하세요.</h2>
      <input
        type="number"
        step={1000}
        onChange={e => setMoney(e.target.value)} // 5
      ></input>
      <h2>입금 또는 출금 버튼을 클릭하세요</h2>
      <button onClick={clickDeposit}>입금</button> // 6
      <button onClick={clickWithdraw}>출금</button>
      <h2>현재 잔액: {state}</h2> // 7
    </div>
  )
}

export default App

① useReducer함수에 넣을 reducer 함수를 설정합니다.
② useReducer함수를 이용한 state를 초기화 합니다.
③ input에서 입력한 숫자를 담아 놓을 state를 설정합니다.
④ 클릭했을 때 dispatch 함수를 실행할 함수를 설정합니다.
⑤ input 태그에서 입력 이벤트가 발생하면, money의 값이 재할당 됩니다.
⑥ click 이벤트가 발생했을 때 해당 함수를 실행합니다.
⑦ state값이 브라우저에서 보여줍니다.


🔵 문제 3

🔵 풀이

import React, { useReducer, useState } from 'react'

const uid = () => { // 1
  let a = new Uint32Array(3)
  window.crypto.getRandomValues(a)
  return (
    performance.now().toString(36) +
    Array.from(a)
      .map(A => A.toString(36))
      .join('')
  ).replace(/\./g, '')
}

const personReducer = (state, action) => { // 2
  switch (action.type) {
    case 'ADD':
      return {
        ...state,
        member: [...state.member, { ...action.info }],
        count: ++state.count,
      }
    case 'DELETE':
      let filteredMembers = state.member.filter(one => one.id !== action.idx)
      return {
        ...state,
        member: [...filteredMembers],
        count: --state.count,
      }
    default:
      return state
  }
}

const App = () => {
  const [state, dispatch] = useReducer(personReducer, { // 3
    count: 0,
    member: [],
  })
  const [info, setInfo] = useState({}) // 4

  const changeHandler = e => // 5
    setInfo({ ...info, id: uid(), [e.target.name]: e.target.value })

  console.log(info)

  const addPerson = () => { // 6
    dispatch({ type: 'ADD', info: info })
  }

  const deletePerson = e => { // 7
    dispatch({ type: 'DELETE', idx: e.target.value })
  }

  return (
    <div>
      <div>
        <h1>전체 회원 수 : {state.count}</h1> // 8
        <div>
          <label>이름 : </label>
          <input
            type={'text'}
            name="name"
            onChange={changeHandler} // 9
            autoComplete="off"
          ></input>
        </div>
        <div>
          <label>나이 : </label>
          <input
            type={'number'}
            name="age"
            onChange={changeHandler // 9
            autoComplete="off"
          ></input>
        </div>
        <div>
          <label>주소 : </label>
          <input
            type={'text'}
            name="address"
            onChange={changeHandler} // 9
            autoComplete="off"
          ></input>
        </div>

        <button onClick={addPerson}>추가</button>
      </div>

      <table>
        <thead>
          <tr>
            <th>이름</th>
            <th>나이</th>
            <th>지역</th>
            <th>삭제</th>
          </tr>
        </thead>
        <tbody>
          {state.member.map((person, idx) => ( // 10
            <tr key={idx}>
              <td>{person.name}</td>
              <td>{person.age}</td>
              <td>{person.address}</td>
              <td>
                <button onClick={deletePerson} value={person.id}> // 11</button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

export default App
  • ① 랜덤 id 값을 만들 함수를 설정합니다. (ex. 생성값: nstssst4bzlqavq92k5g3qbj3niax)
  • ② useReducer함수에 넣을 reducer 함수를 설정합니다.
  • ③ useReducer함수를 이용한 state를 초기화 합니다.
  • ④ input 태그에서 입력할 때 값을 담을 state를 설정합니다.
  • ⑤ input 태그에서 onChange 이벤트가 발생할 때 실행할 함수를 설정합니다.
    • [e.targetname] 에 의해서 key값이 동적으로 들어갑니다.
  • ⑥ 클릭했을 때 dispatch 함수를 실행할 함수(addPerson)를 설정합니다.
    • input에서 입력받아서 만들어진 info 값을 action으로 넣습니다.
  • ⑦ 클릭했을 때 dispatch 함수를 실행할 함수(deletePerson)를 설정합니다.
    • 이벤트가 발생한 태그의 value(id)값을 action에 넣어줍니다.
  • ⑧ state의 속성인 count값(전체 회원 수)을 브라우저에서 보여줍니다.
  • ⑨ onChange 이벤트가 발생하면, info에 동적으로 값이 삽입됩니다.
  • ⑩ state.member 값으로 map() 함수를 돌려줍니다.
  • ⑪ 버튼 태그에 value값으로 id값을 넣어줍니다.
    • 또 이벤트가 발생했을 때 삭제하는 함수(deletePerson)를 실행하도록 합니다.

🌱 나가면서

  • 문제를 풀어보면서 useReducer 함수를 사용해 봤습니다.
  • useReducer는 useState 처럼 컴포넌트의 상태를 관리할 때 사용하는 Hooks 입니다.
  • useState는 컴포넌트 안에서만 사용해야 합니다.
  • useReducer는 컴포넌트 상태 업데이트 로직을 컴포넌트에서 분리 가능합니다.
  • 즉, 다른 컴포넌트에서도 해당 로직을 재사용 가능합니다.
  • 이처럼 상태 값을 컴포넌트에 분리할 수 있는 이점이 있는 만큼, 많이 사용되는 React Hook 입니다.
  • 추가적인 useReducer 함수 참고는 아래 링크를 이용하시면 좋습니다😀 수고하셨습니다👍

🌱 참고


'새싹DT 기업연계형 프론트엔드 실무 프로젝트 과정 8주차 블로그 포스팅'
profile
Here and Now. 🧗‍♂️

0개의 댓글