2022. 2. 8. 15:45ใWEB Dev/ToyProject
๐ท CloneTodo โ - Todomate Clone Project | Team CloneMate
CloneTodo : ๋ง์ ์ฌ๋๋ค์ด ์ฌ๋ํ๋ ํฌ๋๋ฉ์ดํธ๋ฅผ ํด๋ก ํ์ฌ ์น ์๋น์ค๋ฅผ ๋ฐฐํฌํด๋ณด๋ ํ๋ก์ ํธ
1. ํ ์ผ ํด๋ฆญ ์ ๋ฑ์ฅ ๋ชจ๋ฌ
์ด์ ๋ฟ๋ ค์ง ํ ์ผ์ ํด๋ฆญํ๋ฉด 5๊ฐ์ ๋ฒํผ์ด ์๋ ๋ชจ๋ฌ์ฐฝ์ ๋์์ผ ํ๋ค.
์ด ๋ชจ๋ฌ์ ํด๋น ํ ์ผ์ ์ ๋ณด๋ฅผ ๋ณ๊ฒฝํด์ฃผ๋ ๊ธฐ๋ฅ์ ํ๋ค.
๋ชฉํ ์ค์ ํ ๋ ์ผ๋ MUI Dialog UI๋ฅผ ์ธ๊น๋ ์๊ฐํ๋๋ฐ ๋จ์ํ ๋ฒํผ๋ง ์์ผ๋ฉด ๋์ด์ ์ด๋ฒ์๋ Modal์ ์ ์ฉํด๋ณด์๋ค.
์๋ณธ๊ณผ ๋น์ทํ ์ฌ์ด์ฆ๋ก ๋ชจ๋ฌ์ ์ปจํ ์ด๋์ ๋ฒํผ์ ๊ตฌํํ๋ค.
{/* ๋ชจ๋ฌ ์์ฑ */}
<TodoModal
modalOpen={modalOpen} handleTodoModalClose={handleTodoModalClose}s
electedTodo={selectedTodo}
clickTodoEditHandler={clickTodoEditHandler}
clickTodoDeleteHandler={clickTodoDeleteHandler} />
export function TodoModal (props) {
const modalOpen = props.modalOpen;
const handleTodoModalClose = props.handleTodoModalClose;
const selectedTodo = props.selectedTodo;
const clickTodoEditHandler = props.clickTodoEditHandler;
const selectedInputIndex = props.selectedInputIndex;
const clickTodoDeleteHandler = props.clickTodoDeleteHandler;
return(
<Modal open={modalOpen}
onClose={handleTodoModalClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
className="feed-todo-modal-box"
>
<Box className="feed-todo-modal-wrap" >
<p className="feed-todo-modal-head">{selectedTodo.title}</p>
<Box className="feed-todo-modal-icon-wrap">
<button className="feed-todo-edit-icon" onClick={clickTodoEditHandler} data-index={selectedInputIndex} ><EditIcon className="feed-modal-icon" /><span>์์ </span></button>
<button className="feed-todo-delay-icon" data-index={selectedInputIndex} ><SkipNextIcon className="feed-modal-icon" /><span>๋ด์ผ ํ๊ธฐ</span></button>
<button className="feed-todo-date-change-icon" data-index={selectedInputIndex} ><SyncAltIcon className="feed-modal-icon" /><span>๋ ์ง ๋ฐ๊พธ๊ธฐ</span></button>
<button className="feed-todo-order-change-icon" data-index={selectedInputIndex} ><WrapTextIcon className="feed-modal-icon" /><span>์์ ๋ณ๊ฒฝ</span></button>
<button className="feed-todo-delete-icon" data-index={selectedInputIndex} ><DeleteOutlineIcon className="feed-modal-icon" onClick={clickTodoDeleteHandler} data-index={selectedInputIndex} /><span>์ญ์ </span></button>
</Box>
</Box>
</Modal>
)
}
๋ชจ๋ฌ์ on/off ํ๊ณ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํจ์๋ค์ ๊ตณ์ด atom์ ๋ฃ์ง ์์๋ ๋ ๊ฒ ๊ฐ์์ props๋ก ์ ๋ฌํ๋ค.
๋ชจ๋ฌ์ ์ด๋ฏธ MUI์์ ๋ด๋ถ ์ด๋ฒคํธ๊ฐ ๋ค ๊ตฌํ์ด ๋์ด ์๊ธฐ ๋๋ฌธ์ madalOpen ์ด๋ผ๋ props์ true, false ๋ถ๋ฆฌ์ธ ๊ฐ๋ง ์ ์ฉํด์ฃผ๋ฉด ๋๋ค. ํด๋น ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ์๋์ ๊ฐ๋ค.
/* ๋ชจ๋ฌ ๊ด๋ จ */
//ํฌ๋ ํด๋ฆญ ์ ๋ชจ๋ฌ ๋ฑ์ฅ ์ด๋ฒคํธ ํธ๋ค๋ฌ
const clickTodoModalHandler = (e) => {
// console.log("click index", e.currentTarget.dataset.key)
let todoIndex = e.currentTarget.dataset.key;
handleTodoModalOpen()
setSelectedTodo(selectedTodo = todo[todoIndex])
setSelectedInputIndex(todoIndex);
}
// ํฌ๋ ํด๋ฆญ์ ๋ชจ๋ฌ ๋
ธ์ถ on off
const handleTodoModalOpen = () => setModalOpen(true);
const handleTodoModalClose = () => setModalOpen(false);
todo ๊ฐ์ ๋ง๋ index๋ฅผ ์ป์ด๋ด์ผ ํ๊ธฐ ๋๋ฌธ์ dataset ์ ์ด์ฉํ๋ค.
todo.map ์ผ๋ก ๋ฟ๋ฆฌ๊ณ ์๋ <input> ํ๊ทธ์ (์ด์ ๊น์ง๋ InputBase MUI ๋ฅผ ์ด์ฉํ๋๋ฐ, readOnly ์ค์ ์ด ์ ์๋จนํ์ HTML ๊ธฐ๋ณธ ํ๊ทธ์ธ input์ผ๋ก ๋ณ๊ฒฝํ๋ค.)
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ถ๊ฐํด์ฃผ๊ณ data-index ๋ํ ์ถ๊ฐํด์ฃผ์ด์ e.target์ ๋ด๊ฒจ ์ค๋๋ก ํ๋ค.
โป data-oo ์์ฑ์ผ๋ก ์ ๋ณด ์ฌ์ฉํ๊ธฐ
ํ์ฌ map์ผ๋ก index๋ฅผ ๋ฟ๋ ค์ค ์ ์๊ธฐ ๋๋ฌธ์ ๊ฐ input ํ๊ทธ์ data ์ ๋์ฌ๋ฅผ ์ด์ฉํด ์ ๋ณด๋ฅผ ๋ด์ ์ค ์ ์๋ค.
์ด๋ฐ data ์ ๋์ฌ๋ฅผ dataset ์ด๋ผ๊ณ ํ๋๋ฐ
<element data-item="itisdata"></element> ์ฒ๋ผ ์ฌ์ฉํ ๋ค์
onclick์ด๋ onchange ๋ฑ ์ ๋ณด ๋ณ๊ฒฝ์ ์บ์นํ ์ ์๋ ์ด๋ฒคํธ ํจ์๋ค์์ ์ฌ์ฉํ ๋๋
e.target.dataset.item ์ด๋ ๊ฒ ์ฌ์ฉํ ์ ์๋ค. ์ด ๋๋ "itisdata"๊ฐ ๋์ด์ค๊ฒ ๋๋ค.
์ด data-index๋ฅผ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ํด๋นํ๋ ์ ๋ณด๋ฅผ ์ ๋ถ ๋ชจ๋ฌ์ ์ ๋ฌํ ์๊ฐ ์์๋ค.
๋์ todo ์๋ณธ ๋ฐ์ดํฐ๋ฅผ ๋ฝ์ ์ ๋ฌํ๋ ๊ฒ์ด ์๋๋ผ ํด๋ฆญํ๋ฉด selectedTodo๋ผ๋ state๋ฅผ ์์ฑํด ํด๋ฆญํ ์ ๋ณด๊ฐ์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ค.
ํ ์ผ ์์ ๋ชจ๋ฌ ๊ธฐ๋ฅ
1. ์์
์ ํํ index์ todo input ๋ถ๋ถ์ readOnly ์ํ ๋ณ๊ฒฝ ํ ๋ฐ์์จ todo State๋ฅผ ์์ ํด์ ๋ค์ recoil์ ๋ฐ์
2. ๋ ์ง๋ฐ๊พธ๊ธฐ
ํด๋น todo State์ date ๊ฐ์ ๋ณ๊ฒฝ ํด ์ค๋ค.
3. ์ค๋ ํ๊ธฐ
ํด๋น todo State์ date ๊ฐ์ ์ค๋๋ก ๋ณ๊ฒฝ
4. ์์ ๋ณ๊ฒฝ
ํด๋น ๋ ์ง์ todo state๋ฅผ ๋ณ๋์ ์ปดํฌ๋ํธ (ํ์ด์ง) ๋ก ์ด๋์์ผ์ ๋๋๊ทธ๋ก order ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋๋ก ํ๋ค.
์... drag ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์จ์ผ๊ฒ ์ง?
5. ์ญ์
์ ํํ index์ todo๋ฅผ ์ญ์ ํด recoil์ ๋ฐ์
์ต์ข ์์ ๋ recoil todo state๋ ํ์ด์ง ๋ฒ์ด๋ ๋ api๋ฅผ ํตํด ์ ๋ฐ์ดํธ ์ํค๋๋ก ํ๋ค.
2. ์์ / ์ญ์ ๊ธฐ๋ฅ
๋ชจ๋ฌ์์ ์์ ๋ฒํผ์ ํด๋ฆญํ๋ฉด input์ readonly ์์ฑ์ด true์์ false๋ก ๋ณํด์ผ ํ๋ค.
readonly ์์ฑ์ ์ฃผ๋ ์ด์ ๋ '์์ ' ์ํ๊ฐ ์๋๋ฉด input ์์ฒด๊ฐ list์ ๊ธฐ๋ฅ๋ ํจ๊ป ํด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
readonly๋ ๊ทธ์ผ๋ง๋ก '์ฝ๊ธฐ์ ์ฉ' ์ํ๋ผ ์ฝ๊ธฐ ์ ์ฉ์ด๋ฉด ์ฐ๊ธฐ๊ฐ ์๋๋ true ์ํ๋ฉด ์ฐ๊ธฐ๋ฅผ ํ ์ ์๊ณ false๋ฉด ์ฐ๊ธฐ๊ฐ ๊ฐ๋ฅํด์ง๋ค.
MUI์ InputBase์์๋ readonly๋ฅผ ์ ์ฉํ ์ ์๋๋ฐ ์ํ๊ฐ์ ๋ฐ๊ฟ๋ ์ ์ฉ์ด ์๋์ด์ input์ ์ฌ์ฉํ๊ธฐ๋ก ํ๋ค.
๋์ CSS์ border์ outline ์ 0์ผ๋ก ์์ ํด์ ์์ฑํ์ง ์์ ๋๋ ๋ฆฌ์คํธ์ฒ๋ผ ๋ณด์ด๋๋ก ํ๋ค.
์์ ๊ธฐ๋ฅ
์์ ์ด ์ข ๊ณ ๋์ด๋์๋๋ฐ readonly ์์ฑ์ด ์ ์๋ฐ๋์ด์ ํด๊ฒฐํ๋๋ผ๊ณ ์ดํ์ ์๋นํ๋ค. InputBase๋ฅผ ํฌ๊ธฐํ๋ ๊ฒ์ผ๋ก ํ๊ณ input์ผ๋ก ๋ฐ๊พธ๋ ์ด๋ ๊ฒ ๊ฐ๋จํ ํด๊ฒฐ์ด ๋๋๊ฑธ...!
์์ ๋ํ ํด๋ฆญํ ํ ์ผ๋ง readonly๊ฐ false๊ฐ ๋์ด์ผ ํด์ ๋ชฉํ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ๊ตฌํํ ๋ ๊ฒ์ฒ๋ผ ๋ฐฐ์ด์ ์์ฑํ๋ค.
์๋ todo์ readonly ์์ฑ๋ recoil๋ก ๊ด๋ฆฌํ๋ ค๊ณ ํ์ง๋ง ๊ตณ์ด recoil๋ก ์๋ค๊ฐ๋ค ํ ํ์๊ฐ ์ ํ ์์ด์
ํด๋น ์ปดํฌ๋ํธ์์ ๊ด๋ฆฌํ ์ ์๋๋ก ์ ๋ฆฌํ๋ค.
let [todoReadOnly, setTodoReadOnly] = useState(Array(todo.length).fill(true));
๊ทธ๋ฆฌ๊ณ ์ด state ๋ํ todo๊ฐ map์ผ๋ก ๋ฟ๋ ค์ง๋ ๋์ index๋ก ๊ด๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์ readOnly ์์ฑ์ ๋ฐฐ์ด๋ก ๋ฟ๋ ค์ฃผ์๋ค.
todo.map((todo,index)=>{
return (
<Box className="goals-todo-input-list-Box" key={index} onClick={clickTodoModalHandler} data-key={index}>
{goal.goal_id === parseInt(todo.goal_id) ? (<>
<div className="goals-todo-input-list-check-wrap">
<CheckBoxOutlineBlankIcon className="goals-todo-list-input-check-icon"/>
<input
key={`todo${index}`} readOnly={todoReadOnly[index]} type="text" maxLength={"35"} name={todo.title} data-index={index} id="todo-input" value={todo.title} onChange={todoEditEventHandler} onKeyDown={enterKeyEventHandler} className="goals-todo-list-input" />
</div>
<Button className="goals-todo-list-input-btn" ><MoreHorizIcon className="goals-todo-list-input-btn-icon" /></Button>
</>
) : null}
</Box>
)
})
์ด๋ ๊ฒ readonly ์์ฑ์ ๊ฐ๋ณ๋ก ์ค ์ ์๊ฒ ๋๋ฉด value๊ฐ์ e.target.value๋ก ๋ฐ์์์ ์์ ๋๊ฒ ํ๋ฉด ๋๊ฒ ๊ตฌ๋ ํ๊ณ ์ฝ๊ฒ ์๊ฐํ๋๋ฐ, ์๊ฐ๋ณด๋ค ์ค๋ฅ๊ฐ ๋ง์ด ๋ฐ์ํ๋ค.
e.target.value๋ฅผ recoil๋ก ๋ฐ์์จ todo ๊ฐ์ฒด์ title์ state๋ณ๊ฒฝ ํจ์๋ก ๋ฃ์ผ๋ ค๊ณ ํ๋๋
cannot set properties of undefined (setting 'title') ์ค๋ฅ๊ฐ ์์ฒญ ๋ด๋ค.
๊ฒฐ๊ตญ ์ฐพ์๋ณด๋ฉด ํด๋น title์ ์์ ํ ์ ์๋ '์ฝ๊ธฐ ์ ์ฉ' ์ด๋ผ๋ ๊ฑฐ์๋๋ฐ ์คํ์ค๋ฒํ๋ก์ฐ์์๋ ... ๋ฅ ์นดํผ๋ฅผ ์ด์ฉํ๋ผ๊ณ ํ์ผ๋ ์ด๋ฏธ ๋ฅ ์นดํผ๋ฅผ ์ด์ฉํ๊ณ ์์๋ค.
์ด๊ฒ ์๋๋ฉด JSON์ ํ ์คํธ๋ก ๋ณํํ๋ค๊ฐ ๋ค์ ํ์ฑํ๋ผ๊ณ ํด์ ํด๋ดค๋๋ฐ๋ ์๋๋๋ผ.
ํด๊ฒฐ ๋ฐฉ๋ฒ์ useRecoilState๋ก ๋ฐ์์จ todo ๊ฐ์ฒด๋ฅผ originTodo๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ฐ์์ ๋ฏธ๋ฆฌ ๋ฅ ์นดํผํ๊ณ , ๊ทธ๊ฑธ ํจ์์์ ๋ฐ์ JSON ํ์ฑ์ ํด์ recoilState์ ์์ ๊ด๋ จ์๋ ๊ฐ์ฒด๋ก ๋ง๋ค์ด๋ฒ๋ฆฐ ๋ค์์ setOriginTodo๋ก ๋ฎ์ด์์ฐ๋ ๋ฐฉ์์ ์ฌ์ฉํ๋ ์ ์์ ์ผ๋ก recoil์ ์ ๋ฐ์ดํธ ๋์๋ค.
์ฝ๋๋ ์๋์ ๊ฐ๋ค.
let [originTodo, setOriginTodo] = useRecoilState(todoData); //recoil์ ์๋ todo ์๋ณธ ๊ฐ์ฒด
let todo = [...originTodo]; //originTodo Deep Copy
//ํฌ๋ ํด๋ฆญ-์์ ๋ฒํผ ์ด๋ฒคํธ ํธ๋ค๋ฌ - ํฌ๋ ํด๋ฆญํ์ ๋
const clickTodoEditHandler = (e) => {
const index = e.currentTarget.dataset.index;
const newArr = Array(todo.length).fill(true);
newArr[index] = false;
setTodoReadOnly(newArr)
handleTodoModalClose();
}
//ํฌ๋ ์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ
const todoEditEventHandler = (e) => {
let index = parseInt(e.target.dataset.index);
let value = e.target.value;
const originTodo = JSON.parse(JSON.stringify(todo)); // todo State ์นดํผ
originTodo[index].title = value;
setOriginTodo(originTodo) ; //setOriginTodo๋ฅผ ์ด์ฉํด state ๋ณ๊ฒฝ
}
CSS ๋ฅผ ์ฝ๊ฐ ์์ ํด ์์ฐ์ค๋ฝ๊ฒ ๋ง๋ค์ด ์ฃผ๋ ์๋์ ๊ฐ์ด ๋์ํ๋ค.
maxLength๋ 35์๋ก ์ค์๊ณ ๋ชจ๋ฌ์์๋ 2์ค ์ด์ ๋ ธ์ถ๋์ง ์๋๋ก text-overflow: ellipsis;๋ฅผ ์ฃผ์๋ค.
๋ฐ๊นฅ ์ชฝ์ ํด๋ฆญํ๊ฑฐ๋ ์ํฐ๋ฅผ ์ณค์ ๊ฒฝ์ฐ ์์ฐ์ค๋ฝ๊ฒ readOnly๊ฐ ๋ฐ๋๋ฉด์ ์๋์ผ๋ก submit์ด ๋๋ ๊ฒ ๊ฐ์ด ๋ณด์ด๊ธฐ ์ํด์ ๋ ๊ฐ์ง์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๊ตฌํํ๋ค.
๊ฐ๊ฐ input์ onKeyDown๊ณผ onBlur๋ก ์ ์ฉํ๋ค.
<input key={`todo${index}`} id="todo-input" className="goals-todo-list-input" type="text" maxLength={"80"}
name={todo.title} data-index={index} readOnly={todoReadOnly[index]} value={todo.title}
onChange={todoEditEventHandler} onKeyDown={enterKeyEventHandler}
onBlur={inputLostFocusEventHandler} />
//์ธ๋ถ ํด๋ฆญ readonly ๋ณ๊ฒฝ
const inputLostFocusEventHandler = (e) => {
let newArr = Array(todo.length).fill(true);
setTodoReadOnly(newArr)
}
//ํฌ๋ ์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ
const clickTodoEditHandler = (e) => {
console.log("ํ์ฌ ์ธ๋ฑ์ค ", e.currentTarget.dataset.index)
const index = e.currentTarget.dataset.index;
const newArr = Array(todo.length).fill(true);
newArr[index] = false;
console.log("newArr[index]", index, newArr[index], newArr)
setTodoReadOnly(newArr)
handleTodoModalClose();
}
์ญ์ ๊ธฐ๋ฅ
์์ ๊ธฐ๋ฅ์ด ํ๋ ์ ํ๋ ค์ ์ญ์ ๋ฅผ ๋จผ์ ๋ง๋ค์์๋ค. ๊ตฌ์กฐ๋ ๋ชฉํ ๋์ ๋๊ฐ์ง๋ง ์ด๋ฒ์ filter๋ก ๊ฑธ๋ฌ๋ผ ์๊ฐ ์์๋ค.
์๋๋ฉด ํ์ฌ todo ๊ฐ์ฒด์ index ๊ฐ์ ์ด์ฉํด์ ๋ชจ๋ ์ ๋ณด๋ฅผ ์ฒ๋ฆฌํ๊ณ ์์๊ธฐ ๋๋ฌธ์
์ญ์ ๋ฅผ ์ํด์ goal_id์ todo_id๋ฅผ ๋น๊ตํด์ ๋ง๋ ๊ฐ์ ์ฐพ์ filter๋ก ๊ฑธ๋ฌ๋ด๋ ๋ณต์กํ ๋ฐฉ์์ ๊ตฌํํ๊ณ ์ถ์ง ์์๋ค.
todo๊ฐ ์ด์จ๋ ์์๋ฅผ ๊ฐ์ง ๋ฐฐ์ด๋ก ๋ฐ์์ฌ ์ ์๊ณ ์ํ ๊ฐ๋ฅํ ์ ๋ณด.. ์ด๊ธฐ ๋๋ฌธ์ index๋ก ๊ตฌํํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ฝ๊ณ ๋นจ๋๋ค๊ณ ์๊ฐํ๋คใ
๊ทธ๋์ ๊ตฌํํ ๊ฒ์ ์๋์ ๊ฐ๋ค. ๋ชจ๋ฌ์ delete ๋ฒํผ์ onClick์ผ๋ก ์ฐ๊ฒฐํด ์ฃผ์๊ณ ํด๋ฆญํ๋ฉด ์ฆ์ ์ญ์ ๋๋๋ก ํ์๋ค.
//ํฌ๋ ์ญ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ
const clickTodoDeleteHandler = (e) => {
let index = parseInt(e.currentTarget.dataset.index);
const originTodo = [...todo]; // todo State ์๋ณธ ์นดํผ
originTodo.splice(index, 1) //์๋ณธ todo ๋ฐฐ์ด์์ ํด๋น index ์ฐพ์์ 1๊ฐ ์ญ์
setOriginTodo(originTodo) ;//setOriginTodo๋ฅผ ์ด์ฉํด state ๋ณ๊ฒฝ
handleTodoModalClose();
}
์ด๊ฑด spliceํ ๊ฑฐ๋ผ ์์ ์์ ๊ฒช์ ๊ฒ ์ฒ๋ผ '์ฝ๊ธฐ ์ ์ฉ' ์ค๋ฅ๊ฐ ๋จ์ง๋ ์์๋ค. ๊ทธ๋ฌ๋ ์์ ์ ๋ง๋ค๊ณ ๋์ ๋ฅ ์นดํผํ todo๋ฅผ ๋ค์ ๋ฅ ์นดํผํด์ ์ฌ์ฉํ๋ค.
์๋ณธ ๋ถ๋ณ์ ๋ฒ์น์ ์์ง ๋ง๊ณ ๋ฅ ์นดํผํด์ ์ฌ์ฉํ์. ์๊พธ ๋ ๊ฒ์ ์ ๋ณด๋ฅผ ๋ฏ์ด์ ์ฌ์ฉํ๋ ค๊ณ ํ๋๊น ์ค๋ฅ๊ฐ ๋ฌ๋ค.
๊ทธ๋ฆฌ๊ณ ์์ ์ด๊ฑด ์ญ์ ๊ฑด ๋ฒํผ์ ํด๋ฆญํ๋ฉด ๋ชจ๋ฌ์ด ์ฌ๋ผ์ ธ์ผ ํ๊ธฐ ๋๋ฌธ์ handleTodoModalClose() ํจ์๋ฅผ ์คํ์์ผ ๋ชจ๋ฌ์ด ์ข ๋ฃ๋ ์ ์๋๋ก ํด์ค๋ค.
์ด์ ํ ์ผ์ 3๊ฐ์ ๋ ์ง, ์์ ๋ณ๊ฒฝ ๋ฒํผ๊ณผ ์ฒดํฌ๋ฅผ ํด๋ฆญํ๋ฉด ์๋ฃ ์ฌ๋ถ state๊ฐ ๋ณ๊ฒฝ๋ ์ ์๋๋ก ํ๋ ๊ฒ์ด๋ค..!
'WEB Dev > ToyProject' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ToyProject-Todomate] ํฌ๋๋ฉ์ดํธ ํด๋ก ํ๋ก์ ํธ 38 (0) | 2022.03.21 |
---|---|
[ToyProject-Todomate] ํฌ๋๋ฉ์ดํธ ํด๋ก ํ๋ก์ ํธ 35 (0) | 2022.02.08 |
[ToyProject-Todomate] ํฌ๋๋ฉ์ดํธ ํด๋ก ํ๋ก์ ํธ 34 (0) | 2022.02.03 |
[ToyProject-Todomate] ํฌ๋๋ฉ์ดํธ ํด๋ก ํ๋ก์ ํธ 33 (0) | 2022.02.01 |
[ToyProject-Todomate] ํฌ๋๋ฉ์ดํธ ํด๋ก ํ๋ก์ ํธ 32 (0) | 2022.01.26 |