useReducer

useReducer

์‚ฌ์šฉ๋ฒ• #1

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

// reducer - state๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ์—ญํ• (์€ํ–‰)
// dispatch - state ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•œ ์š”๊ตฌ
// action - ์š”๊ตฌ์˜ ๋‚ด์šฉ

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

const reducer = (state, action) => {
  console.log('reducer is working', 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>
  );
}

export default App;

์‚ฌ์šฉ๋ฒ• #2

useReducer.jsx

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

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: [
    // {
    //   id: Date.now(),
    //   name: 'James',
    //   isHere: false,
    // },
  ],
};

function App() {
  const inputRef = useRef('asd');
  const [name, setName] = useState('');
  const [studentsInfo, dispatch] = useReducer(reducer, initialState);
  console.log(studentsInfo);

  const clearAndFocusInput = () => {
    setName('');
    inputRef.current.focus();
  };

  const handleKeyDown = (e) => {
    if (e.key === 'Enter') {
      nameDispatch();
    }
  };

  const nameDispatch = () => {
    dispatch({ type: 'add-student', payload: { name } });
    clearAndFocusInput();
  };

  return (
    <div>
      <h1>์ถœ์„๋ถ€</h1>
      <p>์ด ํ•™์ƒ ์ˆ˜: {studentsInfo.count}</p>
      <input
        ref={inputRef}
        onKeyDown={handleKeyDown}
        placeholder="์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <button onClick={nameDispatch}>์ถ”๊ฐ€</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;

Student.jsx

import React from 'react';

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

export default Student;

Last updated