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