🏃‍♂️

React100本ノック③ ~TODO編~

2024/03/20に公開

はじめに

前回に続き今回はTODOを実装していきます!TODOはReactロードマップの方でも一度実装したことがあったので割とスムーズにできました。以下参考にさせていただいた記事と前回の自分の記事です。
https://qiita.com/Sicut_study/items/5dec3c42c8f3c90f0487
https://zenn.dev/hirohiro_sys/articles/aeab3b5404390b

実装

App.tsx
import { useState } from "react";
import styled from "styled-components";
import Incomplete from "./Incomplete";
import Input from "./Input";

const OuterDiv = styled.div`
   display: flex;
   flex-direction: column;
   justify-content: center;
   align-items: center;
   height: 100vh;
`
const InnerDiv = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  border: 2px solid black;
  border-radius: 100px;
  padding: 60px 80px;
  background-color: #daeeae; 
`

function App() {
  const [todoText,setTodoText] = useState<string>("");
  const [incompleteTodos, setIncompleteTodos] = useState<string[]>([]);
  const onClickAdd = () => {
    if (todoText==="") return;
    const newTodos = [...incompleteTodos,todoText];
    setIncompleteTodos(newTodos);
    setTodoText("");
  }
  const onClickDelete = (index: number) => {
    const newTodos = [...incompleteTodos];
    newTodos.splice(index,1);
    setIncompleteTodos(newTodos);
  }
  return (
    <OuterDiv>
      <InnerDiv>

      <h1><i>-TODO-</i></h1>
      <Input todoText={todoText} setTodoText={setTodoText} onClickAdd={onClickAdd}/>
      <Incomplete todos={incompleteTodos} onClickDelete={onClickDelete}/>

      </InnerDiv>
    </OuterDiv>
  );
}

export default App;
Input.tsx
import React, { MouseEventHandler } from "react";

interface InputProps {
  todoText: string;
  setTodoText: React.Dispatch<React.SetStateAction<string>>;
  onClickAdd: MouseEventHandler<HTMLButtonElement>;
}
const Input: React.FC<InputProps> = (props) => {
  const {todoText,setTodoText,onClickAdd} = props;
  return (
    <div>
      <input
        placeholder="TODOを入力"
        value={todoText}
        onChange={(e) => setTodoText(e.target.value)}
      />
      <button onClick={onClickAdd}>追加</button>
    </div>
  );
};

export default Input;
Incomplete.tsx
import React from "react";
import styled from "styled-components";

const SDiv = styled.div`
    display: flex;
    align-items: center;
`
const SButton = styled.button`
    margin-left: 20px;
`
interface IncompleteProps {
  todos: string[];
  onClickDelete: (index: number) => void;
}

const Incomplete: React.FC<IncompleteProps> = (props) => {
  const { todos, onClickDelete } = props;
  return (
    <div>
      <ul>
        {todos.map((todo: string, index: number) => (
          <li key={todo}>
            <SDiv>
              <p>{todo}</p>
              <SButton onClick={() => onClickDelete(index)}>削除</SButton>
            </SDiv>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default Incomplete;

TypeScriptでのReact学習をまだしていないので今回はGPTにTypeScriptにしてもらいました。またモーダル等は実装してませんが達成条件は全て満たしているのでこれでよしとします。

おわりに

次はTimerです!

Discussion