function EditTodoModal({ status, todosState, todo }) {
const onSubmit = (e) => {
e.preventDefault();
const form = e.currentTarget;
form.content.value = form.content.value.trim();
if (form.content.value.length == 0) {
alert('할 일 써');
form.content.focus();
return;
}
// todosState.addTodo(form.content.value);
// form.content.value = '';
// form.content.focus();
};
return (
<>
<Modal
open={status.opened}
onClose={status.close}
className="tw-flex tw-justify-center tw-items-center">
<div className="tw-bg-white tw-p-10 tw-rounded-[20px] tw-w-full tw-max-w-lg">
<form onSubmit={onSubmit} className="tw-flex tw-flex-col tw-gap-2">
<TextField
minRows={3}
maxRows={10}
multiline
name="content"
autoComplete="off"
variant="outlined"
label="할 일 써"
defaultValue={todo?.content}
/>
<Button variant="contained" className="tw-font-bold" type="submit">
수정
</Button>
</form>
</div>
</Modal>
</>
);
}
// modify v1
const modifyTodo = (id, content) => {
const newTodos = todos.map((todo) => (todo.id != id ? todo : { ...todo, content }));
setTodos(newTodos);
};
const modifyTodoByIndex = (index, newContent) => {
const newTodos = todos.map((todo, _index) =>
_index != index ? todo : { ...todo, content: newContent },
);
setTodos(newTodos);
};
// modify v2
const modifyTodoById = (id, newContent) => {
const index = findTodoIndexById(id);
if (index == -1) {
return null;
}
modifyTodoByIndex(index, newContent);
};
const removeTodo = () => {
if (confirm(`${status.todoId}번 할 일을 삭제하시겠습니까?`) == false) {
status.close();
return;
}
todosState.removeTodo(status.todoId);
status.close();
};
<Snackbar open={open} autoHideDuration={4000} onClose={() => setOpen(false)}>
<Alert variant="filled" severity="sucess">
게시물 삭제됨
</Alert>
</Snackbar>
function NoticeSnackbar({ status }) {
return (
<>
<Snackbar
open={status.opened}
autoHideDuration={status.autoHideDuration}
onClose={status.close}>
<Alert variant={status.variant} severity={status.severity}>
{status.msg}
</Alert>
</Snackbar>
</>
);
}
function useNoticeSnackbarStatus() {
const [opened, setOpened] = React.useState(false);
const [autoHideDuration, setAutoHideDuration] = React.useState(null);
const [variant, setVariant] = React.useState(null);
const [severity, setSeverity] = React.useState(null);
const [msg, setMsg] = React.useState(null);
const open = (msg, severity = 'success', autoHideDuration = 1000, variant = 'filled') => {
setOpened(true);
setMsg(msg);
setSeverity(severity);
setAutoHideDuration(autoHideDuration);
setVariant(variant);
};
const close = () => {
setOpened(false);
};
return {
opened,
open,
close,
autoHideDuration,
variant,
severity,
msg,
};
}
장점 : 편하다
단점 : 공유 데이터는 상위 컴포넌트에서 정의 되어야 한다.
예) 컴포넌트들
import {
RecoilRoot,
atom,
useRecoilState
} from "https://cdn.skypack.dev/recoil";
const page1NoAtom = atom ({
key : 'app/page1NoAtom',
default : 0,
});
function Page1() {
const [no, setNo] = useRecoilState(page1NoAtom);
return (
<>
<h3>페이지1</h3>
<ul>
<li>페이지 1의 숫자 : {no}</li>
<li>
<button onClick={() => setNo(no + 1)}>페이지 1의 숫자 증가</button>
</li>
<li>
<button onClick={() => setNo(no - 1)}>페이지 1의 숫자 감소</button>
</li>
</ul>
</>
);
}
const page2NoAtom = atom ({
key : 'app/page2NoAtom',
default : 0,
});
function Page2() {
const [no, setNo] = useRecoilState(page2NoAtom);
return (
<>
<h3>페이지2</h3>
<ul>
<li>페이지 2의 숫자 : {no}</li>
<li>
<button onClick={() => setNo(no + 1)}>페이지 2의 숫자 증가</button>
</li>
<li>
<button onClick={() => setNo(0)}>페이지 2 숫자 초기화</button>
</li>
</ul>
</>
);
}
const pageNoAtomFamily = atomFamily({
key: "app/pageNoAtomFamily",
default: (no) => 0
});
function Page1() {
const [no, setNo] = useRecoilState(pageNoAtomFamily(1));
return (
<>
<h3>페이지1</h3>
<ul>
<li>페이지 1의 숫자 : {no}</li>
<li>
<button onClick={() => setNo(no + 1)}>증가</button>
</li>
</ul>
</>
);
}
function Page2() {
const [no, setNo] = useRecoilState(pageNoAtomFamily(2));
return (
<>
<h3>페이지2</h3>
<ul>
<li>페이지 2의 숫자 : {no}</li>
<li>
<button onClick={() => setNo(no + 1)}>증가</button>
</li>
</ul>
</>
);
}
function Page3() {
const [no, setNo] = useRecoilState(pageNoAtomFamily(2));
return (
<>
<h3>페이지3</h3>
<ul>
<li>페이지 3의 숫자 : {no}</li>
<li>
<button onClick={() => setNo(no + 1)}>증가</button>
</li>
</ul>
</>
);
}
function Page4() {
const [no, setNo] = useRecoilState(pageNoAtomFamily(1));
return (
<>
<h3>페이지4(페이지1의 데이터를 공유 받음)</h3>
<ul>
<li>페이지 4의 숫자 : {no}</li>
<li>
<button onClick={() => setNo(no + 1)}>증가</button>
</li>
</ul>
</>
);
}