TILs

52일차 TIL (Lv.1과제 .ts 파일로 리팩토링 / **)

API284 2023. 7. 28. 15:29

void ?

void는 TypeScript에서 함수의 반환 타입으로 사용되는 특별한 타입

함수가 어떤 값을 반환하지 않을 때 void를 반환 타입으로 명시할 수 있다

예를 들어, 아래와 같이 void를 반환 타입으로 지정하면, 함수가 어떤 값을 반환하지 않을 것을 나타낼 수 있다

 

function sayHello(): void {
  console.log('Hello, World!');
}

 

void는 반환 값이 없음을 명시하는 역할을 한다

함수가 return 구문을 사용하지 않거나, return 구문이 있더라도 반환값을 명시적으로 지정하지 않을 때 사용

함수형 컴포넌트에서도 void를 반환 타입으로 지정할 수 있다.

예를 들어, 다음과 같이 React.FC와 void를 함께 사용하여 함수형 컴포넌트를 정의할 수 있다.

 

import React from 'react';

const MyComponent: React.FC = () => {
  const handleClick = (): void => {
    console.log('Button clicked!');
  };

  return <button onClick={handleClick}>Click Me</button>;
};

export default MyComponent;

 

이 경우, MyComponent는 React.FC로 정의되었으며, handleClick 함수는 void를 반환

즉, 해당 컴포넌트는 어떤 값을 반환하지 않으며, 버튼을 클릭할 때 콘솔에 메시지가 출력될 뿐

 

 

 

app. tsx 코드

 

import React from "react";
import { useState } from "react";
import "./Tab.css";
import Tabs from "./components/Tabs";
import DefaultBtn from "./components/DefaultBtn";

interface Tab {
    id: number;
    title: string;
    detail: string;
    isDone: boolean;
}

const App: React.FC = () => {
    const [tabs, setTabs] = useState<Tab[]>([
        {
            id: 1,
            title: "React 공부하기",
            detail: "React 기초에 대하여",
            isDone: false,
        },
        {
            id: 2,
            title: "JS 공부하기",
            detail: "문제 풀기 & 복습",
            isDone: false,
        },
        {
            id: 3,
            title: "러닝 40분",
            detail: "3:1 비율로 인터벌",
            isDone: false,
        },
    ]);
    const [title, setTitle] = useState<string>(""); // title 상태의 타입 지정
    const [detail, setDetail] = useState<string>(""); // detail 상태의 타입 지정

    // 초기값 tabs 이후에 추가되는 tabs을 만들어줄 함수를 선언해준다;
    const addHandler = () => {
        if (title === "" || detail === "") {
            alert("입력란을 채워 주세요.");
            return;
        }

        const newTab: Tab = {
            id: tabs.length + 1,
            title: title,
            detail: detail,
            isDone: false,
        };

        // setTabs((prevTabs) => [...prevTabs, newTab]);
        // 기존 할 일 목록에 새로운 항목 추가
        setTabs([...tabs, newTab]);

        setTitle("");
        setDetail("");
    };

    const deleBtn = (id: number) => {
        const newTabs = tabs.filter((tab) => tab.id !== id);
        setTabs(newTabs);
    };

    const toggleBtn = (id: number) => {
        const doneTab = tabs.find((tab) => tab.id === id);

        if (doneTab) {
            doneTab.isDone = !doneTab.isDone;
            const newDoneTab = tabs.filter((tab) => tab.id !== id);
            setTabs([...newDoneTab, doneTab]);
        }
    };

    // 진행 중인 일과 완료한 일을 구분하여 필터링
    const workingOnTab = tabs.filter((tab) => !tab.isDone);
    const finallyDoneTab = tabs.filter((tab) => tab.isDone);

    return (
        <div className="appBody">
            <header className="appHeader">
                <h1>My ToDoList</h1>
                <h1>React</h1>
            </header>
            <div className="appInput">
                <label className="titleLable">제목</label>
                <input
                    autoFocus
                    value={title}
                    onChange={(e) => setTitle(e.target.value)}
                />
                <label className="detailLable">내용</label>
                <input
                    value={detail}
                    onChange={(e) => setDetail(e.target.value)}
                />
                <button onClick={addHandler}>등록하기</button>
            </div>
            <h1 style={{ padding: "10px 0 0 20px" }}>Working On 🔥</h1>
            <div className="tabBody">
                {workingOnTab.map((tab) => (
                    <Tabs
                        tab={tab}
                        key={tab.id}
                        deleBtn={deleBtn}
                        toggleBtn={toggleBtn}
                    />
                ))}
            </div>
            <h1 style={{ padding: "10px 0 0 20px" }}>Finally Done 🎉🎉</h1>
            <div className="doneBody">
                {finallyDoneTab.map((tab) => (
                    <Tabs
                        tab={tab}
                        key={tab.id}
                        deleBtn={deleBtn}
                        toggleBtn={toggleBtn}
                    />
                ))}
            </div>
        </div>
    );
};

export default App;

 

Tab.tsx 코드

 

import React from "react";
import DefaultBtn from "./DefaultBtn";

interface Tab {
    id: number;
    title: string;
    detail: string;
    isDone: boolean;
}

interface TabsProps {
    tab: Tab;
    deleBtn: (id: number) => void;
    toggleBtn: (id: number) => void;
}

const Tabs: React.FC<TabsProps> = ({ tab, deleBtn, toggleBtn }) => {
    const { id, title, detail, isDone } = tab;

    return (
        <div className={`userTab ${isDone ? "complete" : ""}`}>
            <div className="tabTitle">{title}</div>
            <div className="tabDetail">{detail}</div>
            <div className="btns">
                <button className="redBtn" onClick={() => deleBtn(id)}>
                    삭제
                </button>
                <button className="blueBtn" onClick={() => toggleBtn(id)}>
                    {isDone ? "취소" : "완료"}
                </button>
            </div>
        </div>
    );
};

export default Tabs;

 

DefaultBtn은 오류가 있어서 닫아놨다.

일반 button으로 치환해서 수정해놓았다.