연휴기간 react-hook, styled-components
연습을 위해 CRA를 사용하여 간단한 Todo app을 만들보았다. TodoGithub
API이유로 비공개 repo로 수정됨
useState()
를 사용하여, 초기값으로 비어있는 Object를 선언했다.
추가된 항목들의 완료 / 삭제
가 원활하게 이루어져야 했기 때문에 Object를 사용했고,
항목들의 기본 구조는 { id: { id: id, text: text } }
로 설정했다.
고유한 Id값
은 react-id-generator를 사용했다.
// App.js
const [doItems, setDoItems] = useState({});
const addItems = (e) => {
const { target, key } = e;
if (key === "Enter" && target.value !== "") {
const ID = nextId();
setDoItems({
...doItems,
[ID]: {
id: ID,
text: target.value,
},
});
setValue("");
}
};
setDoItems()
를 사용하여, 기존 doItems + 새로운 항목 추가spread operator를 사용하여, 기존 항목들을 먼저 추가하고 새로운 항목을 추가했다.
항목을 추가할 때 지정했던 Id값
을 활용해서, Do에서 삭제 후 Done에 추가했다.
// App.js
const [doneItems, setDoneItems] = useState({});
const handleComplete = (id) => {
const tempItems = doItems;
setDoneItems({
...doneItems,
[id]: {
id,
text: tempItems[id].text,
},
});
delete tempItems[id];
setDoItems({ ...tempItems });
};
Do
전체를 다른 변수(tempItems)에 할당setDoneItems()
를 사용하여, 기존 doneItems + 새로운 항목 추가setDoItems()
를 사용하여, tempItems의 항목들로 교체 (spread operator)Complete와 마찬가지로 Id값
을 활용해서, 항목들을 삭제했다.
// App.js
const handleDelete = (id, title) => {
let tempItems;
if (title === "Do") {
tempItems = doItems;
delete tempItems[id];
setDoItems({
...tempItems,
});
} else {
tempItems = doneItems;
delete tempItems[id];
setDoneItems({
...tempItems,
});
}
};
setDoItems() / setDoneItems()
를 사용하여, tempItems의 항목들로 교체 (spread operator)Delete에서는 똑같이 생긴 코드가 반복되어서, 효율적으로 수정할 방법이 있을 것 같다.
삼항연산자를 사용해서 코드를 간결하게 수정했다.
const handleDelete = (id, title) => {
const tempItems = title === "Do" ? doItems : doneItems;
delete tempItems[id];
title === "Do"
? setDoItems({ ...tempItems })
: setDoneItems({ ...tempItems });
};
props
를 사용하여 조건에 따라 효과를 다르게 줄 수 있었다.
// Items.js
const Items = ({ id, text, title, handleComplete, handleDelete }) => {
return (
<Container>
<Text>{text}</Text>
<Icon title={title}>
{title === "Do" && (
<Complete onClick={() => handleComplete(id)} />
)}
<CloseBtn title={title} onClick={() => handleDelete(id, title)} />
</Icon>
</Container>
);
};
const Icon = styled.div`
display: flex;
justify-content: ${(props) =>
props.title === "Do" ? "space-between" : "flex-end"};
width: 50px;
`;
Icon
의 props인 title을 조건에 사용하였다.
props를 styled-components
에서 사용하기 위해서는 반드시 props로 넘겨주는 값이 있어야한다.
지렸다 갓흥수