这次将运用之前笔计的内容进行整合做一个TodoList
请关注 sui 前端共学营及其社区,在这里你可以学到前端和 move 合约语言的知识。-
这次使用next框架搭建react项目
npx create-next-app@latest
进入目录启动
npm run dev
可以先进入到src/app/page.tsx
删除他的默认代码便于后续代码书写
可以将此TodoList项目拆开为几个组件。
在src
目录下创建components
组件文件夹在其内创建上面四个tsx文件,先在每个文件写导出的函数(下有参考),然后在page中引用。
function TodoList() {
return (
<>
<h1>Todo List</h1>
</>
)
}
export default TodoList;
导入到page使用
import Image from "next/image";
import styles from "./page.module.css";
import TodoList from "@/components/TodoList";
import AddTodo from "@/components/AddTodo";
import TodoItem from "@/components/TodoItem";
import TodoFilter from "@/components/TodoFilter";
export default function Home() {
return (
<>
<h1>TodoList</>
<AddTodo></AddTodo>
<TodoList></TodoList>
<TodoFilter></TodoFilter>
</>
);
}
Todo一个数组结构,我们需要设置个状态对其进行管理,这里使用useState
默认值就是空数组,我们需要去考虑他所使用的类型。我们可在文档中做记录在src
下创建types.ts
Todo
export interface Todo {
id: number;
text: string;
completed: boolean;
}
状态管理
const [todos, setTodos] = useState<Todo[]>([]);
下面封装对Todo的处理 addTodo:
const addTodo = (text: string) => {
const newTodos = {
id: Date.now(),
text,
completed: false,
}
setTodos([...todos, newTodos]);
}
deleteTodo:
const deleteTodo = (id: number) => {
setTodos(todos.filter((todo) => todo.id !== id));
}
toggleTodo
const toggleTodo = (id: number) => {
setTodos(todos.map(todo => {
if (todo.id === id) {
todo.completed = !todo.completed;
}
return todo;
}))
}
TodoFilter
这个filter
更改当前TodoList列表,交互改变其状态这里需要到设一个状态默认值"all"展现所有Todo
const [filter, setFilter] = useState("all");
const getFilteredTodos = () => {
switch (filter) {
case "all":
return todos;
case "active":
return todos.filter(todo => !todo.completed);
case "completed":
return todos.filter(todo => todo.completed);
default:
return todos;
}
}
export default function Home() {
return (
<>
<h1>Todo List</>
<AddTodo addTodo={addTodo}></AddTodo>
<TodoList todos={getFilteredTodos()} deleteTodo={deleteTodo} toggleTodo={toggleTodo}></TodoList>
<TodoFilter filter={filter} setFilter={setFilter}></TodoFilter>
</>
);
}
AddTodo(这里可能会报错需要在page中加"use client")
import React, { useState } from "react";
interface AddTodoProps {
addTodo: (text: string) => void;
}
function AddTodo({addTodo}: AddTodoProps) {
const [text, setText] = useState('');
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (text.trim() === '') {
return
}
addTodo(text)
setText('')
}
return (
<>
<form onSubmit={handleSubmit}>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<button>新建事项</button>
</form>
</>
)
}
export default AddTodo;
TodoList
import {Todo} from '../types';
import TodoItem from './TodoItem';
interface TodoListProps {
todos: Array<Todo>;
toggleTodo: (id: number) => void;
deleteTodo: (id: number) => void;
}
function TodoList({todos, toggleTodo, deleteTodo }: TodoListProps) {
return (
<>
<ul>
{todos.map(todo => (
<TodoItem key={todo.id} todo={todo} toggleTodo={toggleTodo} deleteTodo={deleteTodo}></TodoItem>
))}
</ul>
</>
)
}
export default TodoList;
TodoItem
import {Todo} from "../types";
interface TodoListProps {
todos: Array<Todo>;
toggleTodo: (id: number) => void;
deleteTodo: (id: number) => void;
}
function TodoItem({todo, toggleTodo, deleteTodo}: any) {
return (
<li style={{textDecoration: todo.completed ? "line-through" : "none"}}>
{todo.text}
<button onClick={() => toggleTodo(todo.id)}>Toggle</button>
<button onClick={() => deleteTodo(todo.id)}>Delete</button>
</li>
)
}
export default TodoItem;
TodoFilter
function TodoFilter({setFilter}:any) {
return (
<div>
<button onClick={()=>setFilter('all')}>All</button>
<button onClick={()=>setFilter('active')}>active</button>
<button onClick={()=>setFilter('completed')}>completed</button>
</div>
)
}
export default TodoFilter;
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!