게시글 등록 페이지, 게시글 수정 페이지
변경사항 없음
함수에 타입스크립트를 적용하는 것을 생각해보면 함수를 호출할 때 타입을 정해주는것이 아니라 함수를 정의한 곳에서 타입을 정의해준다.
함수형 컴포넌트에서도 컴포넌트를 호출하는 곳에서는 타입을 지정해줄 필요 없고 컴포넌트에서 매개변수의 타입을 설정해주면 된다.
Container 컴포넌트
props 의 타입을 지정해준다.
onClickUpdate 안에서 myvariables 객체의 타입을 지정해준다. ( 객체는 타입추론이 안된다 ) .
이벤트의 타입을 지정해준다. ( 이벤트의 타입은 react에서 제공해준다 )
import { useMutation } from "@apollo/client";
import { useState, ChangeEvent } from "react";
import BoardWriteUI from "./BoardWrite.presenter";
import { 나의그래프큐엘세팅, UPDATE_BOARD } from "./BoardWrite.queries";
import { useRouter } from "next/router";
interface IBoardWriteProps {
isEdit: boolean;
data?: any;
}
export default function BoardWrite(props: IBoardWriteProps) {
const router = useRouter();
const [isActive, setIsActive] = useState(false);
const [writer, setWriter] = useState("");
const [title, setTitle] = useState("");
const [contents, setContents] = useState("");
const [나의함수] = useMutation(나의그래프큐엘세팅);
const [updateBoard] = useMutation(UPDATE_BOARD);
const onClickSubmit = async () => {
const result = await 나의함수({
variables: {
// variables === $ 의 역할
writer: writer,
title: title,
contents: contents,
},
});
console.log(result);
router.push(
`/section10/10-02-typescript-boards/${result.data.createBoard.number}`
);
};
const onClickUpdate = async () => {
interface IMyvariables {
number: Number;
writer?: string;
title?: string;
contents?: string;
}
const myvariables: IMyvariables = { number: Number(router.query.number) };
if (writer) myvariables.writer = writer;
if (title) myvariables.title = title;
if (contents) myvariables.contents = contents;
const result = await updateBoard({
variables: {
...myvariables,
},
});
router.push(`/section10/10-02-typescript-boards/${router.query.number}`);
};
const onChangeWriter = (e: ChangeEvent<HTMLInputElement>) => {
setWriter(e.target.value);
if (e.target.value && title && contents) {
setIsActive(true);
}
};
const onChangeTitle = (e: ChangeEvent<HTMLInputElement>) => {
setTitle(e.target.value);
if (writer && e.target.value && contents) {
setIsActive(true);
}
};
const onChangeContents = (e: ChangeEvent<HTMLInputElement>) => {
setContents(e.target.value);
if (writer && title && e.target.value) {
setIsActive(true);
}
};
return (
<div>
<BoardWriteUI
onClickSubmit={onClickSubmit}
onClickUpdate={onClickUpdate}
onChangeWriter={onChangeWriter}
onChangeTitle={onChangeTitle}
onChangeContents={onChangeContents}
isActive={isActive}
isEdit={props.isEdit}
data={props.data} // undefined 이거나, data이거나 둘 중 하나 !
/>
</div>
);
}
presenter 컴포넌트
props 의 타입을 정의해준다.
graphql 에서 받아오는 데이터의 타입은 일단은 any로 두고 추후 공부한 뒤 수정할 예정이다.
import { ChangeEvent, MouseEvent } from "react";
import { BlueButton, RedInput } from "./BoardWrite.style";
interface IBoardWriteUIProps {
onClickSubmit: (event: MouseEvent<HTMLButtonElement>) => void;
onClickUpdate: (event: MouseEvent<HTMLButtonElement>) => void;
onChangeWriter: (event: ChangeEvent<HTMLInputElement>) => void;
onChangeTitle: (event: ChangeEvent<HTMLInputElement>) => void;
onChangeContents: (event: ChangeEvent<HTMLInputElement>) => void;
isActive: boolean;
isEdit: boolean;
data: any;
}
export default function BoardWriteUI(props: IBoardWriteUIProps) {
return (
<div>
<div>
작성자 :{" "}
<RedInput
type="text "
onChange={props.onChangeWriter}
defaultValue={props.data?.fetchBoard.writer}
/>
제목 :{" "}
<input
type="text"
onChange={props.onChangeTitle}
defaultValue={props.data?.fetchBoard.title}
/>
내용 :{" "}
<input
type="text"
onChange={props.onChangeContents}
defaultValue={props.data?.fetchBoard.contents}
/>
<BlueButton
onClick={props.isEdit ? props.onClickUpdate : props.onClickSubmit}
isActive={props.isActive}
>
{props.isEdit ? "수정" : "등록"}하기
</BlueButton>
;
</div>
</div>
);
}
style.ts 컴포넌트
props 의 타입을 정의해준다.
import styled from "@emotion/styled";
interface IBlueButtonProps {
isActive: boolean;
}
const RedInput = styled.input`
border-color: red;
`;
const BlueButton = styled.button`
background-color: ${(props: IBlueButtonProps) => {
return props.isActive ? "yellow" : "";
}};
`;
export { RedInput, BlueButton };
interface를 효율적으로 사용하는 방법
위의 예시 코드들은 각 페이지 안에서 타입들을 정의하고 사용했지만, 재사용성을 높이고 가독성을 높이기 위해서 타입들을 하나의 파일로 관리하고, 각 컴포넌트들은 타입들을 import 해서 사용하는 것이 좋다.
import { ChangeEvent, MouseEvent } from "react";
export interface IBoardWriteProps {
isEdit: boolean;
data?: any;
}
export interface IBlueButtonProps {
isActive: boolean;
}
export interface IMyvariables {
number: Number;
writer?: string;
title?: string;
contents?: string;
}
export interface IBoardWriteUIProps {
onClickSubmit: (event: MouseEvent<HTMLButtonElement>) => void;
onClickUpdate: (event: MouseEvent<HTMLButtonElement>) => void;
onChangeWriter: (event: ChangeEvent<HTMLInputElement>) => void;
onChangeTitle: (event: ChangeEvent<HTMLInputElement>) => void;
onChangeContents: (event: ChangeEvent<HTMLInputElement>) => void;
isActive: boolean;
isEdit: boolean;
data: any;
}
728x90
'Frontend 프론트엔드' 카테고리의 다른 글
[ 29 ] graphql codegen을 이용해서 Type 다운로드 받고 사용하기 (0) | 2024.06.22 |
---|---|
[ 28 ] 유틸리티 타입 정리 feat. Record Type (0) | 2024.06.22 |
[ 26 ] Next.js 에 타입스크립트 설정하기 (0) | 2024.06.21 |
[ 25 ] 게시판 수정하기 실습 2편 (0) | 2024.06.21 |
[ 24 ] 게시판 수정하기 실습 1편 (0) | 2024.06.20 |