WEB/React

useReducer - React Hooks

hatso 2023. 11. 30. 13:01

전체적인 틀

AttendanceBook.js 

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

const reducer = (state, action) => {

}

const initialState = {

}

function AttendanceBook(){
	const [name, setName] = useState("");
    const [] = useReducer(reducer, );
    
    return (
    	<div>
        	<h1></h1>
            <p></p>
            <input/>
            <button>추가</button>
        </div>
    )
}

export default AttendanceBook;

 

구현

import React, { useState, useReducer } from "react";
import Student from "../components/Student";

//reducer는 
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 AttendanceBook(){
	const [name, setName] = useState("");
    const [studentsInfo,dispatch] = useReducer(reducer, initialState);
    
    return (
    	<div>
        	<h1>출석부</h1>
            <p>총 학생 수: {studentsInfo.count}</p>
            <input
            	type="text"
                placeholder="이름을 입력해주세요"
                value={name}
                onChange={(e)=> setName(e.target.value)}
            />
            <button
            	onClick={()=>{
                	dispatch({type: "add-student", payload: {name} });
                }}
            >추가</button>
            //배열 메소드 map()을 통해 Student 컴포넌트를 표기
            {studentsInfo.students.map((student) => {
            	return(
                	<Student
                    	key={student.id}
                        name={student.name}
                        dispatch={dispatch}
                        id={student.id}
                        isHere={student.isHere}
                    />
                );
            })}
        </div>
    )
}

export default AttendanceBook;

Students.js

학생 목록이 표기되는 Component

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({ type: "mark-student", payload: { id } });
                }}
            >
            {name}</span>
            <button
            	onClick={()=> {
                	dispatch({ type: "delete-student", payload: {id} })
                }}
            >
            삭제</button>
        </div>
    );
};

export default Student;

 

 

state(거래내역)를 업데이트하기 위해서 요구라는 Dispatch 작업 내용인 액션을  Reducer에 전달을 해주며, Reducer은 액션의 내용대로 state를 업데이트 시킴

 

 

요구하는 주체(state를 업데이트를 위한 요구) = Dispatch

요구의 내용 = Action

수정하는 역할(state를 업데이트 하는 역할) = reducer

reducer에 의해 변경되는 데이터 = state

 

reducer을 가지고 목적(type)에 맞는 작업을 해줄 수 있게 구현한다면 매우 좋은 react hook이다.

출석부의 데이터 구조가 todolist와 비슷하기 때문에 reducer을 활용해 todolist를 구현해 볼 생각이다.