【Sui】前端共学React学习笔记(4)

这次将运用之前笔计的内容进行整合做一个TodoList

88f9d4b7250a724489ed6e23ff6ea7f.jpg 请关注 sui 前端共学营及其社区,在这里你可以学到前端和 move 合约语言的知识。-

创建项目

这次使用next框架搭建react项目 npx create-next-app@latest 进入目录启动 npm run dev

可以先进入到src/app/page.tsx删除他的默认代码便于后续代码书写

组件设计

可以将此TodoList项目拆开为几个组件。

  • TodoList 用于展示Todo
  • AddTodo 用于增减Todo
  • TodoItem Todo项目
  • TodoFilter 用于筛选Todo

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;

屏幕录制 2025-01-19 221449.gif

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
yuanchengjiayu
yuanchengjiayu
江湖只有他的大名,没有他的介绍。