useReducer

2023. 3. 24. 14:53React

1. 추가

// App.js
import './App.css';
import {useReducer, useState} from "react";
import Student from "./Student";

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

    case 'delete-student' : {
      return
    }
    default:
      return state
  }
}


function App() {
  const [name, setName] = useState('');
  const [studentsInfo, dispatch] = useReducer(reducer, {
    count: 0,
    students: [] //id, name, isHere
  })


  return (
  <div className="App">

    <h1>총학생수 : {studentsInfo.count}</h1>
    <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 name={student.name} key={student.id} />)
    })}
  </div>
  )
}

export default App;

 

 

2. 삭제

// App.js
import './App.css';
import {useReducer, useState} from "react";
import Student from "./Student";

const reducer = (state, action) => {
  switch (action.type) {
    case 'add-student': {
      const newStudent = {
        id: Date.now(),
        name: action.payload.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)
      }

    default:
      return state
  }
}


function App() {
  const [name, setName] = useState('');
  const [studentsInfo, dispatch] = useReducer(reducer, {
    count: 0,
    students: [] //id, name, isHere
  })

  return (
  <div className="App">

    <h1>총학생수 : {studentsInfo.count}</h1>
    <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 name={student.name}
                       key={student.id}
                       dispatch={dispatch}
                       id={student.id}/>)
    })}

  </div>
  );
}

export default App;

Props  dispatch, id 값 내려주기

dispatch={dispatch}
id={student.id}
// Student.js
import React from "react";

const Student = ({name, dispatch, id}) => {
  return (
    <div>
      <span>{name}</span>
      <button onClick={() => dispatch({type: 'delete-student', payload: {id} }) }>삭제</button>
    </div>
  )
}

export default Student

 

 

3. 이름클릭시 라인줄 긋기

case 'mark-student' :
  return {
    count: state.count,
    students: state.students.map(student => {
      if (student.id === action.payload.id) {
        return {...student, isHere: !student.isHere}
      }
    })
  }
{studentsInfo.students.map(student => {
  return (<Student name={student.name}
                   key={student.id}
                   dispatch={dispatch}
                   id={student.id}
                   isHere={student.isHere}/>)
})}
// Student.js
import React from "react";

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

export default Student