APP.js文件
javascript">import { useReducer, createContext, useContext } from "react"
import AddTask from "./components/AddTask"
import TaskList from "./components/TaskList"const initialTasks = [{ id: 0, text: 'Visit Kafka Museum', done: true },{ id: 1, text: 'Watch a puppet show', done: false },{ id: 2, text: 'Lennon Wall pic', done: false }
]
function tasksReducer(tasks, action) {switch (action.type) {case "added":return [...tasks, {id: action.id,text: action.text,done: false}]case "changed":return tasks.map(t => {if (t.id === action.task.id) {return {...action.task, done: !action.task.done}} else {return t}})case "saved":return tasks.map(t => {if (t.id === action.id) {return {...t, text: action.text}} else {return t}})case "deleted":return tasks.filter(t => t.id !== action.id)default:throw Error("Unknown action" + action.type)}
}const TaskContext = createContext(null)
export function useTasks() {return useContext(TaskContext)
}
const TaskDispatchContext = createContext(null)
export function useTasksDispatch() {return useContext(TaskDispatchContext)
}function App() {const [tasks, dispatch] = useReducer(tasksReducer, initialTasks)return (<><TaskContext.Provider value={tasks}><TaskDispatchContext.Provider value={dispatch}><h1>Prague itinerary</h1><AddTask /><TaskList /></TaskDispatchContext.Provider></TaskContext.Provider></>)
}export default App
AddTask.js
javascript">import { useState } from "react"
import { useTasksDispatch } from "../App" export default function AddTask() {const [text, setText] = useState("")const dispatch = useTasksDispatch()return (<><input value={text} placeholder="Add task" onChange={e => {setText(e.target.value)}}></input><button onClick={() => {dispatch({type: "added",id: Date.now(),text: text})setText("")}}>Add</button></>)
}
TaskList.js
javascript">import { useState } from "react"
import { useTasks, useTasksDispatch } from "../App"export default function TaskList() {const tasks = useTasks()return (<ul>{tasks.map(t => ( <li key={t.id}><Item t={t} /></li>))}</ul>)
}function Item({ t }) {const [text, setText] = useState("")const [status, setStatus] = useState(0)const dispatch = useTasksDispatch()return (<><inputchecked={t.done}onChange={e => {dispatch({type: "changed",task: {...t, done: !e.target.checked}})}}type="checkbox" />{!status ?<>{t.text} {" "}<button onClick={e => {setStatus(!status)setText(t.text)}}>Edit</button></>: <><input value={text} onChange={e => {setText(e.target.value)}} /> {" "}<button onClick={e => {setStatus(!status)dispatch({type: "saved",text: text,id: t.id})}}>Save</button></>}<button onClick={e => {dispatch({type: "deleted",id: t.id})}}>delete</button></>)
}