React16 Hooks如何通过ID获取数据并传递给路由编辑组件填充表单
解决方案
1. 引入路由相关钩子
你当前使用的是react-router-dom v5版本的路由语法,直接使用useParams钩子即可获取路由路径中的:id参数,同时引入useHistory用于提交成功后跳转回首页:
import { Link, useParams, useHistory } from 'react-router-dom'
2. 获取路由ID,拉取对应任务填充表单
调整EditTask组件的初始化逻辑,拿到ID后请求对应任务,直接把任务数据填充到表单对应的state中:
const EditTask = () => { const api ="http://localhost:5000" const { id } = useParams() const history = useHistory() // 单个任务初始值改为对象而非数组 const [task, setTask] = useState({}) const [text, setText] = useState('') const [day, setDay] = useState('') const [reminder, setReminder] = useState(false) // 原有tasks状态在当前组件无使用场景,可以直接删除 // const [tasks, setTasks] = useState([]) // 组件挂载/ID变化时拉取单条任务 useEffect(() => { const getSingleTask = async () => { const taskData = await fetchTask(id) setTask(taskData) setText(taskData.text) setDay(taskData.day) setReminder(taskData.reminder) } id && getSingleTask() },[id]) // fetchTask逻辑保持不变 const fetchTask = async (id) => { const res = await fetch(`${api}/tasks/${id}`) const data = await res.json() return data } // ...其余逻辑 }
3. 修正更新提交逻辑
原有更新逻辑使用的是接口拉取的旧任务数据,没有读取用户修改后的表单值,调整如下:
const onSubmit = (e) => { e.preventDefault() updateData() } const updateData = async () => { const updateTask = { text, day, reminder } await fetch(`${api}/tasks/${id}`, { method: 'PUT', headers: { 'Content-type': 'application/json' }, body: JSON.stringify(updateTask) }) // 提交成功跳转回任务列表页 history.push('/') }
4. 可选优化
如果不需要在编辑页预览原有Task组件样式,可以删除form内的<Task task={task}/>代码,避免重复展示任务内容。
修改后完整EditTask代码
import React, {useState, useEffect} from 'react' import { Link, useParams, useHistory } from 'react-router-dom' const EditTask = () => { const api ="http://localhost:5000" const { id } = useParams() const history = useHistory() const [task, setTask] = useState({}) const [text, setText] = useState('') const [day, setDay] = useState('') const [reminder, setReminder] = useState(false) const onSubmit = (e) => { e.preventDefault() updateData() } useEffect(() => { const getSingleTask = async () => { const taskData = await fetchTask(id) setTask(taskData) setText(taskData.text) setDay(taskData.day) setReminder(taskData.reminder) } id && getSingleTask() },[id]) const fetchTask = async (id) => { const res = await fetch(`${api}/tasks/${id}`) const data = await res.json() return data } const updateData = async () => { const updateTask = { text, day, reminder } await fetch(`${api}/tasks/${id}`, { method: 'PUT', headers: { 'Content-type': 'application/json' }, body: JSON.stringify(updateTask) }) history.push('/') } return ( <div> <header className='header'> <h1>Edit</h1> <Link to="/" className="btn btn-primary">Go Back</Link> </header> <form className="add-form" onSubmit={onSubmit}> <div className="form-control"> <label>Task</label> <input type="text" placeholder="Add Task" value={text} onChange={(e)=> setText(e.target.value)} /> </div> <div className="form-control"> <label>Day & Time</label> <input type="text" placeholder="Add Day & Time" value={day} onChange={(e)=> setDay(e.target.value)}/> </div> <div className="form-control form-control-check"> <label>Set Reminder</label> <input type="checkbox" checked={reminder} value={reminder} onChange={(e)=> setReminder(e.currentTarget.checked)}/> </div> <input className="btn btn-block" type="submit" value="Save Task" /> </form> </div> ) } export default EditTask
内容的提问来源于stack exchange,提问作者LOTUSMS
相关产品推荐
相关产品推荐

