react todolist

发布时间 2023-09-17 11:38:13作者: 虎虎生威啊

react todo list

todolist/src/main.jsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

todolist/src/App.jsx

import { useEffect, useState } from "react"

export default function App() {

  const [curTodo, setCurTodo] = useState('')

  const [todos, setTodos] = useState(() => {
    const localValue = localStorage.getItem("ITEMS")
    if (localValue == null) return []
    return JSON.parse(localValue)
  })

  useEffect(() => {
    localStorage.setItem("ITEMS", JSON.stringify(todos))
  }, [todos])

  function addTodo(e) {
    e.preventDefault()
    if (curTodo.length === 0) return
    setTodos(() =>
      [
        ...todos,
        {
          id: crypto.randomUUID(),
          title: curTodo,
          status: false
        }
      ]
    )
    setCurTodo('')
  }

  function toggleTodo(id, status) {
    setTodos(() =>
      todos.map(todo => {
        if (todo.id === id) {
          return { ...todo, status }
        }
        return todo
      })
    )
  }

  function deleteTodo(id) {
    setTodos(() =>
      // 符合这个条件(todo.id !== id)的元素,都会被过滤下来,并将这些元素组成一个数组返回
      todos.filter(todo => todo.id !== id)
    )
  }


  return (
    <>
      <form onSubmit={addTodo}>
        <input type="text" value={curTodo} onChange={e => setCurTodo(e.target.value)} />
        <button>Add</button>
      </form>
      <ul>
        {
          todos.map(todo =>
            <li key={todo.id}>
              <label>
                <input
                  type="checkbox"
                  checked={todo.status}
                  onChange={(e) => toggleTodo(todo.id, e.target.checked)}
                />
                {todo.title}
              </label>
              <button onClick={() => deleteTodo(todo.id)}>Delete</button>
            </li>
          )
        }
      </ul>
    </>
  )
}



todolist/index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

todolist/vite.config.js

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
})

todolist/package.json

{
  "name": "todolist",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.15",
    "@types/react-dom": "^18.2.7",
    "@vitejs/plugin-react": "^4.0.3",
    "eslint": "^8.45.0",
    "eslint-plugin-react": "^7.32.2",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.3",
    "vite": "^4.4.5"
  }
}