id를 길이대신에 uuid로 변경해주고 Work를 type파일을 새로 만들어서 지정해주었다.
const clickAddButtonHandler = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const newWorking: Work = {
id: v4(),
work: title,
content: content,
isDone: false,
};
const updateWorking = [...working, newWorking];
setworking(updateWorking);
localStorage.setItem("todokey", JSON.stringify(updateWorking));
setTitle("");
setContent("");
};
그리고 Cards에 넘겨주는 함수들의 이름도 fnc1, fnc2 대신에 이름을 더 명확하게 변경해주고 수정을 위해 working의 State를 변수로 넘겨준다.
return (
<div className="mytodo">
<div className="title">
<div>My Todo List</div>
<div>React</div>
</div>
<div className="input-form">
<form className="addform" onSubmit={clickAddButtonHandler}>
<Input labelName={"제목"} value={title} Add={titleAddHandler}></Input>
<Input
labelName={"내용"}
value={content}
Add={contentAddHandler}
></Input>
<button className="add-btn">추가하기</button>
</form>
</div>
<div className="list">
<h1>Working..</h1>
<div>
<div className="working">
{working
.filter((work) => {
return work.isDone === false;
})
.map((item) => {
return (
<Cards
key={item.id}
item={item}
deletefnc={clickDeleteButtonHandler}
statefnc={clickCompleteButtonHandler}
working={working}
setwork={setworking}
>
완료
</Cards>
);
})}
</div>
</div>
<h1>Done..!</h1>
<div>
<div className="done">
{working
.filter((work) => {
return work.isDone === true;
})
.map((item) => {
return (
<Cards
key={item.id}
item={item}
deletefnc={clickDeleteButtonHandler}
statefnc={clickCancelButtonHandler}
working={working}
setwork={setworking}
>
취소
</Cards>
);
})}
</div>
</div>
</div>
</div>
);
props의 타입은 다음과 같이 지정해줬다.
export interface CardsType {
key: string;
item: Work;
deletefnc(id: string): void;
statefnc(id: string): void;
working: Work[];
setwork: any;
children: string;
}
수정 기능을 구현하기 위해 useRef를 사용해서 수정 기능이 담긴 class를 찾아 value를 사용할 수 있게 변경하였다.
const updateButtonHandler = () => {
setUpdateState(!updateState);
};
const completeUpdateButtonHandler = (id: string) => {
// 수정 title, content
const findUpdateBoxTitle = (
updateBoxRef.current?.querySelector(".update-title") as HTMLInputElement
).value;
const findUpdateBoxContent = (
updateBoxRef.current?.querySelector(
".update-content"
) as HTMLTextAreaElement
).value;
const newSetting = (id: string) => {
const working: Work[] = props.working;
const newWorking = working.map((data) => {
if (data.id === id) {
return {
...data,
work: findUpdateBoxTitle,
content: findUpdateBoxContent,
};
}
return data;
});
localStorage.setItem("todokey", JSON.stringify([...newWorking]));
props.setwork(newWorking);
};
newSetting(id);
updateButtonHandler();
};
먼저 타입을 지정해주고
export interface UpdateTextType {
item: Work;
}
선언문들을 타입에 맞게 수정해줬다.
const UpdateContent = (props: UpdateTextType) => {
const [newTitle, setnewTitle] = useState<string>(props.item.work);
const [newContent, setnewContent] = useState<string>(props.item.content);
const newTitleHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
setnewTitle(event.target.value);
};
const newContentHandler = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setnewContent(event.target.value);
};
return (
<>
<input
className="update-title"
type="text"
value={newTitle}
onChange={(event) => newTitleHandler(event)}
></input>
<textarea
className="update-content"
value={newContent}
onChange={(event) => newContentHandler(event)}
></textarea>
</>
);
};
props의 타입을 지정해야 하는데 event가 어떤 것인지 감이 안잡혔다.
하지만 해당 event 매개변수에 마우스를 올려보면 어떤 것인지 알려줬다.
const Button = (props: ButtonType) => {
return (
<button
className={props.role}
onClick={(event) => props.fnc(props.para.id, event)}
>
{props.children}
</button>
);
};
TodoType.ts
export interface ButtonType {
role: string;
para: Work;
fnc(id: string, event: React.MouseEvent): void;
children: string;
}
interface Person {
name: string;
}
const alice: Person = { name: 'Alice' }; // 타입은 Person
const bob = { name: 'Bob' } as Person ; // 타입은 Person
타입단언 사용을 지양해야 한다.
정의
재사용성이 높은 컴포넌트를 만들 때 자주 활용되는 특징
타입을 함수의 파라미터처럼 사용하는 것
선언
function getText<T>(text: T): T {
return text;
}
getText<string>('hi');
getText<number>(10);
getText<boolean>(true);
해봤던 내용들이긴 하지만, React에서는 처음 적용해봐서 시간이 오래 걸리는 것 같다. 토요일에는 문서를 더 분석해보면서 공부해봐야겠다