(보너스)보드끼리도 순서 바꾸면 대박!
const useLocalStroage = localStroage.setItem(...)
이런식으로 함수를 만들어서, 값이 업데이트되는 곳에 다 넣어줬는데const localStorageEffect =
(key: string) =>
({ setSelf, onSet }: any) => {
const savedValue = localStorage.getItem(key);
if (savedValue != null) {
setSelf(JSON.parse(savedValue));
// 연결된 atom의 값을 초기화 해주는 함수
}
onSet((newValue: any, _: any, isReset: boolean) => {
// atom의 값이 변경이 되었을 때 실행되는 함수
isReset
? localStorage.removeItem(key)
: localStorage.setItem(key, JSON.stringify(newValue));
});
};
export const toDoState = atom<IToDoState>({
key: "toDo",
// 로컬스토리지에 저장되는 key값
default: {
"To Do": [],
Doing: [],
Done: [],
},
effects: [localStorageEffect("toDo")], <<<----
});
저장도 아주 잘 되고 :)
filter
함수랑 개싸우다가 결국 다른분 코드를 참고해서 작성했다..filter
함수를 가지고 아이디가 다를 경우 삭제되도록 하려고했는데 const [todoList, setToDoList] = useRecoilState(toDoState);
const handleDeleteTodo = (toDoId: number): void => {
setToDoList(todoList => todoList.filter(t => t.toDoId !== toDoId));
};
-- DraggableCard.tsx
interface IDragabbleCardProps {
toDoId: number;
toDoText: string;
index: number;
boardId: string; // 추가
}
function DragabbleCard({
boardId,
toDoId,
toDoText,
index,
}: IDragabbleCardProps) {
// 코드챌린지 - 리스트 삭제
const setTodos = useSetRecoilState(toDoState);
const handleDeleteTodo = (todoId: number): void => {
setTodos((todos: IToDoState) => {
const copiedTodos: IToDo[] = [...todos[boardId]];
const filteredTodos: IToDo[] = copiedTodos.filter(
(todo: IToDo) => todo.id !== todoId
);
const result = { ...todos, [boardId]: filteredTodos };
return result;
});
};
return (
<Draggable draggableId={toDoId + ""} index={index}>
{(magic, snapshot) => (
<Card
isDragging={snapshot.isDragging}
ref={magic.innerRef}
{...magic.dragHandleProps}
{...magic.draggableProps}
>
<span>{toDoText}</span>
<span onClick={() => handleDeleteTodo(toDoId)}>🗑️</span>
</Card>
)}
</Draggable>
);
}
--Board.tsx
.
.
.
{toDos.map((toDo, index) => (
<DragabbleCard
key={toDo.id}
index={index}
toDoId={toDo.id}
toDoText={toDo.text}
boardId={boardId} // 추가
/>
))}
.
.
toDoState
atom 값에 새로운 board 추가하기!-- atoms.tsx
export const toDoState = atom<IToDoState>({
key: "toDo",
// 로컬스토리지에 저장되는 key값
default: {
"To Do": [],
Doing: [],
Done: [],
},
effects: [localStorageEffect("toDo")],
});
useSetRecoilState
함수로 toDoState
값을 가져온다음,useForm
에 입력한 {...register("category")}
값을 toDoState
에 넣어주고, return
하였다-- AddBoard.tsx
const FORM = styled.form`
...
`;
const AddBtn = styled.button`
...
`;
interface IForm {
category: string;
}
function NewBoard() {
const setToDos = useSetRecoilState(toDoState);
const { register, handleSubmit, setValue } = useForm<IForm>();
const onVaild = ({ category }: IForm) => {
setToDos(prev => {
return {
...prev,
[category]: [],
};
});
setValue("category", "");
};
return (
<>
<FORM onSubmit={handleSubmit(onVaild)}>
<input
{...register("category")}
type="text"
id="category_text"
placeholder="Add To Caterogy !"
/>
<AddBtn>
<div>➕</div>
</AddBtn>
</FORM>
</>
);
}
추가도 잘 되고, 삭제도 잘 됨!
--- Board.tsx
function Board({ toDos, boardId }: IBoardProps) {
const SetToDos = useSetRecoilState(toDoState);
const { register, setValue, handleSubmit } = useForm<IFrom>();
const onValid = ({ toDo }: IFrom) => {
const newToDo = {
id: Date.now(),
text: toDo,
};
SetToDos(allBoards => {
const result = {
...allBoards,
[boardId]: [newToDo, ...allBoards[boardId]],
};
return result;
});
setValue("toDo", "");
};
// -- 코드챌린지 - board 삭제하기
const deleteBoard = () => {
SetToDos(allBoards => {
const copyBoards = { ...allBoards };
delete copyBoards[boardId];
return { ...copyBoards };
});
};
return (
<Wrapper>
<Title>{boardId}</Title>
{boardId !== "To Do" && boardId !== "Doing" && boardId !== "Done" && (
<DelBoardBtn onClick={deleteBoard}>❌</DelBoardBtn>
)}
IToDo[]
호출 시그니처 때문에 filter
함수를 사용하지 못해서,delete
연산자를 발견boardId
우측에 deleteBoard
❌ 버튼이 생성되고, 클릭하면 삭제된다.deleteBoard
❌ 버튼을 누르면 삭제된다.리팩토링해야할 부분이 많아 보이지만,
진도를 나가려면.. 다음을 기약..하는걸로...
수정 목록
1. board 가 add board input 화면을 가림. css 수정하기 [ ]
2. 전체적인 CSS ... [ ]