APP.js文件
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
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
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 (
<>
<input
checked={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>
</>
)
}