2022. 1. 5. 00:10ใWEB Dev/ToyProject
๐ท CloneTodo โ - Todomate Clone Project | Team CloneMate
CloneTodo : ๋ง์ ์ฌ๋๋ค์ด ์ฌ๋ํ๋ ํฌ๋๋ฉ์ดํธ๋ฅผ ํด๋ก ํ์ฌ ์น ์๋น์ค๋ฅผ ๋ฐฐํฌํด๋ณด๋ ํ๋ก์ ํธ
์ค๋ ํ ์ผ์ ์ฑ ์ ๋์จ๋๋ก Todo๋ฅผ ์ญ์ ํ๋ ํจ์๋ฅผ ์ถ๊ฐํด๋ณธ๋ค. ํฌ๋๋ฉ์ดํธ์์์ ๋ชฉํ ์ญ์ ๋ฒํผ์ ํ๋จ์ ์๊ณ , ํด๋ฆญํ๋ฉด ์์ฑํ ๋ชฉํ๊ฐ ์ญ์ ๋๋ค.
์๊ฒ์ ๋์ค์ ์๋ฆฌ๋ฐฐ์น์ ๋ฌธ์ ์ผ ๊ฒ ๊ฐ์์ ์ฐ์ ํ๋ฑ ์ญ์ ๊ธฐ๋ฅ์ ๊ตฌํํด๋ณธ๋ค.
MUI์ ListItemSecondaryAction์ ์ด์ฉํด์ ์ญ์ ๋ฒํผ์ ๊ตฌํํ๋ค. ์ด ๋ ์ญ์ ๋ฒํผ ์ปดํฌ๋ํธ๊ฐ ๋ค์ด๊ฐ ๊ณณ์ ์ด์ ์ ๋ง๋ Goals.js ์ปดํฌ๋ํธ์ <ListItem> </ListItem> ์ฌ์ด๊ฐ ๋๊ฒ ๋ค.
๊ทธ๋ฆฌ๊ณ InputBase์ id์ name ์์ฑ์ด ์๋์ง ํ์ธํ๋ค. ์ด id์ name์ด ์ญ์ ํ๊ฑฐ๋ ์์ ํ ๋ ์ด๋ค ๋ชฉํ๋ฅผ ์ง์ ํ๋์ง ํ์ธํด ์ค ์ ์๋ ํค๊ฐ ๋๋ค.
import React from "react";
import { Checkbox, IconButton, InputBase, ListItem, ListItemText } from "@mui/material";
import GoalForm from "./GoalForm";
import { ListItemSecondaryAction } from "@material-ui/core";
export default function Goals(props) {
console.log(props.goal);
let goalItems = props.goal;
let add = props.add;
return (
<>
<GoalForm add={add} />
{
goalItems.map((item, idx) => {
return (
<ListItem className="goals-wrap">
<Checkbox checked={item.done} />
<ListItemText>
<InputBase
inputProps={{ "aria-label": "naked" }}
type="text"
id={item.id}
name={item.id}
value={item.title}
multiline={true}
fullWidth={true}
/>
</ListItemText>
<ListItemSecondaryAction>
<IconButton aria-label="Delete Todo" sx={{ fontSize: '14px' }}>
์ญ์
</IconButton>
</ListItemSecondaryAction>
</ListItem>
);
})
}
</>
);
}
์๋ ์์ด์ฝ์ ์ฌ์ฉํ๋๋ฐ, ๋๋ ์ญ์ ๋ผ๊ณ ์ ํ ๊ธด ๋ฒํผ์ผ๋ก ๋ณํํ ์์ ์ด๋ผ ์ญ์ ๋ผ๋ ํ ์คํธ๋ก ๋ฒํผ์ ๊ตฌํํ๋ค.
๋ฒํผ์ ๊ตฌํํ์ผ๋ ์ด์ ์ญ์ ์ด๋ฒคํธ๋ฅผ ๊ตฌํํ ํจ์๋ฅผ ์์ฑํด์ผํ๋ค. delete() ๋ผ๋ ํจ์๋ฅผ ๋ง๋ค ๊ฑด๋ฐ, ํ์ฌ state๋ฅผ ์ญ์ ํด์ผํ๊ณ , state๋ app.js ์ ์์ผ๋ app.js๋ก ๊ฐ์ ํจ์๋ฅผ ์์ฑํ๊ณ props๋ก ๋๊ฒจ์ค์ผ ํ๋ค. add์ ๊ฐ๋ค.
delete ๋ผ๊ณ ํจ์์ด๋ฆ์ ์์ฑํ๋ฉด ์์ฝ์ด๋ผ๊ณ ์๋๋ค๊ณ ํ๋ค. deleteGoal๋ผ๋ ํจ์์ด๋ฆ์ผ๋ก ๋ฐ๊ฟ์ฃผ๊ณ , add๋ ๋์ผํ๊ณ addGoal ๋ก ํจ์ ์ด๋ฆ์ ๋ฐ๊ฟ์ค๋ค.
//app.js ์ ์์ฑ
//๋ชฉํ ์ถ๊ฐ ํจ์
function addGoal(item){
const thisItems = goal.items; // goal State ์๋ณธ ์นดํผ
item.id = 'ID-' + thisItems.length; //key๋ฅผ ์ํ id ์ถ๊ฐ
item.done = false; // done false๋ก ์ด๊ธฐํ
thisItems.push(item) // ์นดํผํ goal ๋ฆฌ์คํธ์ ์์ดํ
์ถ๊ฐ
goalChange({items: thisItems}); //goalChange๋ฅผ ์ด์ฉํด state ๋ณ๊ฒฝ
console.log('items :', goal.items)
}
//๋ชฉํ ์ญ์ ํจ์
function deleteGoal(item){
const thisItems = goal.items;
console.log('Before Update Items :', goal.items );
const newItems = thisItems.filter(e => e.id !== item.id)
goalChange({items: newItems},()=>{
console.log('Update Items : ', goal.items)
})
}
๋ชฉํ ์ญ์ ํจ์๋ Goals ์ปดํฌ๋ํธ์ ๋ณด๋ด์ ธ์ผ ํ๊ธฐ ๋๋ฌธ์ Goals ์ปดํฌ๋ํธ์ props๋ก ๋ณด๋ด์ค๋ค.
<Route exact path="/goals">
<BasicNavBar/>
<Goals goal={goal.items} add={addGoal} delete={deleteGoal} key={goal.items.id} />
</Route>
์ด์ ์ add ํจ์๋ Goals ์ปดํฌ๋ํธ๋ก ๋ฐ์์ GoalForm์ผ๋ก ํ ๋ฒ ๋ ์ ๋ฌํ๋๋ฐ, ์ด๋ฒ์ ๋ฐ๋ก props๋ก ์ฌ์ฉํ ์ ์๋ค. Goals.js์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํจ์๋ฅผ ๋ง๋ค์ด ์ค๋ค.
function deleteEventHandler() {
props.delete(goalItems)
}
//์ฌ๊ธฐ์ goalItems๋ ์ ๋ฒ์ props.goal์ ๋ฐ์๋ ๋ณ์์ด๋ค.
์ด์ ์ด ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์๊น ๋ง๋ค์ด ๋ ์ญ์ ๋ฒํผ์ ์ฐ๊ฒฐํด์ฃผ๋ฉด ๋๋ค.
//Goals.js
import React from "react";
import { Checkbox, IconButton, InputBase, ListItem, ListItemText } from "@mui/material";
import GoalForm from "./GoalForm";
import { ListItemSecondaryAction } from "@material-ui/core";
export default function Goals(props) {
console.log(props.goal);
let goalItems = props.goal;
let add = props.add;
function deleteEventHandler() {
props.delete(goalItems)
}
return (
<>
<GoalForm add={add} />
{
goalItems.map((item, idx) => {
return (
<ListItem className="goals-wrap">
<Checkbox checked={item.done} />
<ListItemText>
<InputBase
inputProps={{ "aria-label": "naked" }}
type="text"
id={item.id}
name={item.id}
value={item.title}
multiline={true}
fullWidth={true}
/>
</ListItemText>
<ListItemSecondaryAction>
<IconButton aria-label="Delete Todo" onClick={deleteEventHandler} sx={{ fontSize: '14px' }}>
์ญ์
</IconButton>
</ListItemSecondaryAction>
</ListItem>
);
})
}
</>
);
}
๋ค ๋ง๋ค์ด๋๊ณ ์คํํด๋ณด๋ ๋ชฉํ๊ฐ ์ญ์ ๋ ์๋๊ณ ์ฝ์์๋
index.js:1 Warning: State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect().
์ด๋ฐ ๋ฉ์์ง๊ฐ ๋ด๋ค. useState์ ๋ณ๊ฒฝ ํจ์์ ์ฝ๋ฐฑํจ์๋ฅผ ์ฐ์ง ๋ง๋ผ๋ ์ด์ผ๊ธฐ ๊ฐ์๋ฐ (...) ํด๋์ค ์ปดํฌ๋ํธ๋ฅผ ๋ด๋ง๋๋ก ๋ณํํด์ ๊ทธ๋ฐ๊ฐ๋ณด๋ค. goalChange ํจ์์์ ์ฝ๋ฐฑํจ์๋ฅผ ๋นผ์ฃผ์. ์๋ ์ฝ๋ฐฑํจ์๋ ๋๋ฒ๊น console.log๋ฅผ ์ฐ๋๊ฑฐ๋ผ ํฐ ๋ฌธ์ ๋ ์์ ๋ฏ ํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ญ์ ๊ฐ ์๋๋๊ฑด ....
์์ผ๊น? ํจ์ ์ด๋ฒคํธ๋ ์ ์๋ํ๋ ๊ฒ์ผ๋ก ๋ณด์ ๋ฐ์ธ๋ฉ์๋ ๋ฌธ์ ๊ฐ ์๋๋ฐ, id ๊ฐ์ ๋น๊ตํ๋๋ฐ์์ ์ค๋ฅ๊ฐ ์๋ ๊ฒ ๊ฐ๋ค. ๋ค๋ฅธ ๋ฌธ์๋ค์ ๋ ์ฐพ์๋ณด๊ณ ํจ์๋ฅผ ๋ณ๊ฒฝํด์ผ ํ ๊ฒ ๊ฐ๋ค. ์๋ ๋ด๊ฐ ๋ญ๊ฐ ์๋ชป ์์ฑํ๊ฑธ๊นใ ใ
//๋ชฉํ ์ญ์ ํจ์
function deleteGoal(item){
const thisItems = goal.items; // goal State ์๋ณธ ์นดํผ
console.log('Before Update Items :', goal.items );
const newItems = thisItems.filter(e => e.id !== item.id)
goalChange({items: newItems}, console.log('update : ' , newItems)
)
}
์ด๋ ๋ฌผ์ด๋ณผ๋ฐ๊ฐ ์์ผ๋ ๋ต๋ตํ๊ธฐ๋ง ํ๋คใ ใ
e.id๋ item.id๋ฅผ ์ฐ์ด๋ณด๋ ๋ ๋ค undefined๋ค..
๋ญ๊ฐ e.id๊ฐ ์ ๋๋ก ์ ๋ค์ด๊ฐ๊ณ ์๋์ง item.id๊ฐ ์๋ค์ด๊ฐ๋๊ฑฐ ๊ฐ์๋ฐ ์ฐ์ add ํจ์ ๋ ํ๋ ๊ฒ์ฒ๋ผ onClick์ด๋ฒคํธ์ deleteEventHandler์ e๋ฅผ ์ ๋ฌํด์ฃผ๊ธฐ ์ํด์ ํด๋น IconButton์ id ์์ฑ์ ๋ฃ์ด์ฃผ๊ณ , id๋ฅผ deleteGoal ํจ์๋ก ๋ณด๋ด์ฃผ์๋ค.
<IconButton aria-label="Delete Todo" id={item.id} onClick={deleteEventHandler} sx={{ fontSize: '14px' }}>
์ญ์
</IconButton>
function deleteEventHandler(e) {
console.log( 'id : ', e.target.id)
props.deleteGoal(e.target.id, goalItems)
}
๊ทธ๋ฆฌ๊ณ deleteGoal ํจ์์ ์ธ์๋ฅผ ๋ ๊ฐ ๋ฐ๋๋ก ํด์ ํด๋ฆญํ list์ id ๊ฐ๊ณผ goal state๋ฅผ ๋ฐ์ ์ ์๋๋ก ํ๋ค.
//๋ชฉํ ์ญ์ ํจ์
function deleteGoal(targetId, item){
const thisItems = item; // goal State ์๋ณธ ์นดํผ
console.log('Before Update Items :', item );
const newItems = thisItems.filter(e => e.id !== targetId)
goalChange({items: newItems})
}
์ด๋ ๊ฒ ํ๋ ์ญ์ ๊ฐ ๋๋ค... ๊ฐ๋ ใ ใ ใ ใ ใ ใ
์ ํํ๊ฒ ๋ญ๊ฐ ๋ฑ ํ๋ ค์ ๊ทธ๋ฌ๋ค! ์ค๋ช ํ๊ธฐ๋ ์ด๋ ค์ด๋ฐ ์ด๋ ๊ฒ ํด๊ฒฐํ๊ณ ๋๋ ๋ญ๊ฐ ๊ตฌ์กฐ๋ฅผ ์๊ฒ๋ ๊ฑฐ ๊ฐ๊ณ ๋ฟ๋ฏํ๊ธฐ๋ง ํ๋ค.... ์ค๋์ ํธํ๊ฒ ์ ๋ค ์ ์๊ฒ ๋ค...
'WEB Dev > ToyProject' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ToyProject-Todomate] ํฌ๋๋ฉ์ดํธ ํด๋ก ํ๋ก์ ํธ 24 (0) | 2022.01.11 |
---|---|
[ToyProject-Todomate] ํฌ๋๋ฉ์ดํธ ํด๋ก ํ๋ก์ ํธ 23 (0) | 2022.01.06 |
[ToyProject-Todomate] ํฌ๋๋ฉ์ดํธ ํด๋ก ํ๋ก์ ํธ 21 (0) | 2022.01.04 |
[ToyProject-Todomate] ํฌ๋๋ฉ์ดํธ ํด๋ก ํ๋ก์ ํธ 20 (0) | 2022.01.02 |
[ToyProject-Todomate] ํฌ๋๋ฉ์ดํธ ํด๋ก ํ๋ก์ ํธ 19 (0) | 2021.12.28 |