Todoアプリ改修
前回行った改修の続きとして、今回は完了ボタンを押し、完了エリアへ移動するボタンの実装です。
まずは完了エリアとなる以下のようにコンポーネントを作りました。
この部分は他のコンポーネント見ながら作ったので、すぐに出来ました。
import React from "react";
import "../styles/style.scss";
interface TodoCompleted {
items: { id: string; text: string }[];
onBackTodo: (id: string, text: string) => void;
}
const CompleteTodo: React.FC<TodoCompleted> = (props) => {
const { items, onBackTodo } = props;
return (
<div className="complate">
<p className="complate-head">完了Todo</p>
<ul>
{items.map((todo) => (
<li key={todo.id}>
<span>{todo.text}</span>
<button className="todoBack" onClick={onBackTodo.bind(null, todo.id, todo.text)}>
戻す
</button>
</li>
))}
</ul>
</div>
);
};
export default CompleteTodo;
次にどのように実装したら、完了エリアにTodoが行ってくれるか。。。
まずはuseStateが必要だと思い、
const App: React.FC = () => {
const [todos, setTodos] = useState<Todo[]>([]);
const [completeTodo, setCompleteTodo] = useState<Todo[]>([]);⇨追記したもの
上記のcompleteTodoの状態が、完了ボタンが押されたタイミングで変わっていればいいので、
次のように書いてます。
簡単にお伝えするとsetTodos関数で未完了エリアにあるTodoを削除して、
setCompleteTodoで削除されたTodoを完了エリアへ
const todoCompletedHandler = (todoId: string, text: string) => {
setTodos((prevTodo) => prevTodo.filter((todo) => todo.id !== todoId));
setCompleteTodo((prevTodo) => [
...prevTodo,
{ id: Math.random().toString(), text: text },
]);
};
しっかり以下もやってます。
<TodoList
items={todos}
onDeleteTodo={todoDeleteHandler}
onCompleteTodo={todoCompletedHandler}
/>
<CompleteTodo items={completeTodo} onBackTodo={todoBackHandler} />
学んだこと
ここで学んだものは、useStateです。
例えば以下のようなuseState。
const [todos, setTodos] = useState<Todo[]>([]);
今の認識はtodosは箱でsetTodosはその箱(todos)の状態を変更する関数。
useStateの<>の部分はtodosをどういう型なのか表している。
Todo[]はインターフェースで以下のように定義済み。
export interface Todo {
id: string;
text: string;
}
ソースコード
以下のソースコード公開中です。
どうぞ見てやってください!
今回は以上です。
ありがとうございました。