Wii Pointer #1 Tilt Normal
본문 바로가기
📁 𝐫𝐮𝐧𝐭𝐢𝐦𝐞𝐄𝐧𝐯𝐢𝐫𝐨𝐧𝐦𝐞𝐧𝐭/React.js

[React .hook] How to use useReducer ?

by 개발자_후니 2024. 2. 21.
728x90
반응형
Before we start

 

useReducer가 무엇인지 어떤 상황에서 사용해야하는지는

 

해당 글에서 정리해놓았다.

 

useReducer가 처음이라면, 아래의 글을 읽고 오는것을 추천한다.

 

2024.02.21 - [📁 𝐫𝐮𝐧𝐭𝐢𝐦𝐞𝐄𝐧𝐯𝐢𝐫𝐨𝐧𝐦𝐞𝐧𝐭/React.js] - [React .hook] What is useReducer ?

 

[React .hook] What is useReducer ?

Before we start 시작하기에 앞서... 필자는 useReducer에 대해서 정말 알지 못한다. 기본적으로 자주 사용되는 React hook들은 한번쯤은 사용 해보았고 어디에 사용하는지 라도 알고있지만, useReducer는 정

jrogrammer.tistory.com

 

So how to use useReducer ?

 

간단한 state 를 업데이트 할 수 있는 useReducer 예제
import React, { useState, useReducer } from 'react';

// reducer - state를 업데이트 하는 역할 (은행)
// dispatch - state 업데이트를 위한 요구
// action - 요구의 내용

const ACTION_TYPES = {
    deposit: 'deposit',
    withdraw: 'withdraw',
};

const reducer = (state, action) = > {
    switch (action.type) {
    	case ACTION_TYPES.deposit:
            return state + action.payload;
        case ACTION_TYPES.withdraw:
            return state - action.payload;
        default:
            return state;
    }
};

function App() {
    const [number, setNumber] = useState(0);
    const [money, dispatch] = useReducer(reducer, 0);
    
    return(
    	<div>
            <h2>useReducer 은행에 오신것을 환영합니다.</h2>
            <p>잔고: {money}원</p>
            <input
            	type="number"
                value={number}
                onChange={(e) => setNumber(parseInt(e.target.value))}
                step="1000"
            />
            <button
            	onClick={() => {
                    dispatch({ type: ACTION_TYPES.deposit, payload: number });
                })
            >
            	예금
            </button>
            <button
            	onClick={() => {
            	    dispatch({ type: ACTION_TYPES.withdraw, payload: number });
                })
            >
            	출금
            </button>
        </div>
    );
};

 

 

조금 더 복잡한 State를 업데이트 할 수 있는 예제
//src/App.jsx

import React, { useState, useReducer } from 'react';
import Student from './Students';

const reducer = (state, action) => {
  switch (action.type) {
    case 'add-student':
      const name = action.payload.name;
      const newStudent = {
        id: Date.now(),
        name,
        isHere: false,
      };
      return {
        count: state.count + 1,
        students: [...state.students, newStudent],
      };
    case 'delete-student':
      return {
        count: state.count - 1,
        students: state.students.filter(
          (student) => student.id !== action.payload.id
        ),
      };
    case 'mark-student':
      return {
        count: state.count,
        students: state.students.map((student) => {
          if (student.id === action.payload.id) {
            return { ...student, isHere: !student.isHere };
          }
          return student;
        }),
      };
    default:
      return state;
  }
};

const initialState = {
  count: 0,
  students: [],
};

function App() {
  const [name, setName] = useState('');
  const [studentsInfo, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <h1>출석부</h1>
      <p>총 학생 수: ?</p>
      <input
        type='text'
        placeholder='이름을 입력해주세요'
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <button
        onClick={() => {
          dispatch({ type: 'add-student', payload: { name } });
        }}
      >
        추가
      </button>
      {studentsInfo.students.map((student) => {
        return (
          <Student
            key={student.id}
            name={student.name}
            dispatch={dispatch}
            id={student.id}
            isHere={student.isHere}
          />
        );
      })}
    </div>
  );
}

export default App;
//src/Students.js

import React from 'react';

const Student = ({ name, dispatch, id, isHere }) => {
  return (
    <div>
      <span
        style={{
          textDecoration: isHere ? 'line-through' : 'none',
          color: isHere ? 'gray' : 'black',
        }}
        onClick={() => {
          dispatch({ tpye: 'mark-student', payload: { id } });
        }}
      >
        {name}
      </span>
      <button
        onClick={() => {
          dispatch({ type: 'delete-student', payload: { id } });
        }}
      >
        삭제
      </button>
    </div>
  );
};

export default Student;

 

이 글을 마치며...

 

해당 useReducer의 예제들을 살펴보면

 

여러개의 state들을 한개의 이벤트가 발생했을 때 여러개의 state값의 변화가 필요할 때

 

사용하는게 효율적이어 보인다.

 

따라서 여러개의 state값의 변경이 필요한 부분이라면

 

useState 말고 useReducer를 써보는 프로젝트를 한번 해봐야할 것 같다.

 

해당 글은 아래의  별코딩 유튜버님의 영상을 참고하여 제작하였습니다.

* 해당 저작물 관련하여 개인적으로 posting permission 받았습니다.

 

https://www.youtube.com/watch?v=tdORpiegLg0

 

728x90
반응형