【React】TodoList 小案例

慈云数据 2024-04-14 技术支持 58 0

page.tsx

"use client"
IMPort AddTodo from "@/components/AddTodo";
import Todolist from "@/components/TodoList";
import TodoFilter from "@/components/TodoFilter";
import {useState} from "react";
import {Todo} from "@/types";
export default function Home() {
    // todos 为事项对象数组 { id: number, text:string, completed:boolean }
    const [todos, setTodos] = useState([])
    const [filter, setFilter] = useState('all')
    const addTodo = (text: string) => {
        const newTodo = {
            id: Date.now(),
            text,
            completed: false
        }
        setTodos([...todos, newTodo])
    }
    const deleteTodo = (id:number) => {
        setTodos(todos.filter(todo=> todo.id !== id))
    }
    const toggleTodo = (id: number) => {
        setTodos(todos.map(todo=> {
            if (todo.id === id) {
                todo.completed =  !todo.completed
            }
            return todo
        }))
    }
    const getFilteredTodos = () => {
        switch (filter) {
            case 'completed':
                return todos.filter(todo => todo.completed)
            case 'active':
                return todos.filter(todo => !todo.completed)
            default:
                return todos
        }
    }
    return (
        
            

TodoList

) }

AddTodo.tsx

import React, {useState} from "react";
interface AddTodoProps {
    addTodo: (text: string) => void
}
function AddTodo({addTodo}: AddTodoProps) {
    const [text, setText] = useState('')
    const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault()
        if (text.trim() === '') {
            return
        }
        addTodo(text)
        setText('')
    }
    return (
        
             setText(e.target.value)}/>
            新建事项
        
    )
}
export default AddTodo

TodoFilter.tsx

interface SetFilterProps {
    setFilter: (text: string) => void
}
function TodoFilter ({ setFilter }: SetFilterProps){
    return (
        
            setFilter('all')}>全部
            setFilter('active')}>待办
            setFilter('completed')}>已办
        
    )
}
export default TodoFilter

TodoItem.tsx

import {Todo} from "@/types";
interface TodoListProps {
    todo: Todo
    toggleTodo: (id: number) => void
    deleteTodo: (id: number) => void
}
function TodoItem({todo, toggleTodo, deleteTodo}: TodoListProps) {
    return (
        {textDecoration: todo.completed ? 'line-through': 'none'}}
            {todo.text}
             toggleTodo(todo.id)}>切换
             deleteTodo(todo.id)}>删除
        
    )
}
export default TodoItem

TodoList.tsx

import {Todo} from "@/types";
import TodoItem from "@/components/TodoItem";
interface TodoListProps {
    todos: Array
    toggleTodo: (id: number) => void
    deleteTodo: (id: number) => void
}
function TodoList({todos, toggleTodo, deleteTodo}: TodoListProps) {
    return (
        
    {todos.map(todo => ( ))}
) } export default TodoList

types.ts

export interface Todo {
    id: number
    text: string
    completed: boolean
}

image.png

微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon