React输入框无法修改值求助:从数据库取值后无法编辑
问题根源与解决方案
你的问题核心是输入框绑定的数据源和更新的数据源完全脱节:输入框显示的是Redux中feedback的原始数据,但handleInputChange更新的是组件自己的state,导致输入时视图毫无反应;提交时又用了Redux里的旧数据,根本没用到用户修改后的值。
按以下步骤修改即可解决:
1. 同步Redux数据到组件内部状态
当Redux从数据库获取到反馈数据后,把它同步到组件的state中,确保输入框初始显示正确值:
// 原获取数据的useEffect保留,新增同步逻辑 useEffect(() => { dispatch(getSingleFeedback(id)); }, [id, dispatch]); // 新增:监听feedback变化,同步到组件state useEffect(() => { if (feedback?.id) { // 确保数据存在再更新 setState(feedback); } }, [feedback]);
2. 绑定输入框到组件内部状态
把所有输入框/下拉框的数据源从Redux的feedback改成组件自己的state:
// 原代码:const { category, detail, title, status } = feedback; // 修改为从组件state解构 const { category, detail, title, status } = state;
输入框的value保持用这些变量即可,现在已经和组件状态双向绑定。
3. 提交时使用组件的最新状态
修改提交函数,用组件state里的最新数据去dispatch更新动作,而不是Redux里的旧feedback:
const editFeedback = async (e) => { e.preventDefault(); dispatch(editFeedbackInit(id, state)); // 传state而非feedback navigate("/"); // 提交后跳转回首页 };
同时修正按钮的点击事件,不需要额外传id(组件已通过useParams拿到):
<EditFeedbackButtonAdd onClick={editFeedback}>Edit Feedback</EditFeedbackButtonAdd>
4. 优化状态更新逻辑
把handleInputChange改成函数式更新,避免状态更新的竞态问题:
const handleInputChange = (e) => { const { name, value } = e.target; setState(prevState => ({ ...prevState, [name]: value })); };
修改后的完整核心代码片段
const EditFeedbackPage = () => { const initialState = { category: "All", comments: [], detail: "", id: nanoid(), createdAt: Timestamp.now().toDate(), status: "Suggestion", title: "", upVotesCount: [] }; const [state, setState] = useState(initialState); const { feedback } = useSelector((state) => state.data); const { category, detail, title, status } = state; const params = useParams(); const { id } = params; const dispatch = useDispatch(); const navigate = useNavigate(); const cancelAddFeedback = () => { navigate("/"); }; useEffect(() => { dispatch(getSingleFeedback(id)); }, [id, dispatch]); useEffect(() => { if (feedback?.id) { setState(feedback); } }, [feedback]); const editFeedback = async (e) => { e.preventDefault(); dispatch(editFeedbackInit(id, state)); navigate("/"); }; const handleInputChange = (e) => { const { name, value } = e.target; setState(prev => ({ ...prev, [name]: value })); }; return ( <EditFeedbackFormContainer> <h4>Feedback Title</h4> <label htmlFor="title">Add a short, descriptive headline</label> <input type="text" name='title' value={title} onChange={handleInputChange} /> <h4>Category</h4> <label htmlFor="category">Change a category for your feedback</label> <select name="category" id="category" value={category} onChange={handleInputChange} > <option value="All">All</option> <option value="UI">UI</option> <option value="UX">UX</option> <option value="Enhancement">Enhancement</option> <option value="Bug">Bug</option> <option value="Feature">Feature</option> </select> <h4>Update Status</h4> <label htmlFor="status">Change feedback status</label> <select name="status" id="status" value={status} onChange={handleInputChange} > <option value="Suggestion">Suggestion</option> <option value="Planned">Planned</option> <option value="In-Progress">In-Progress</option> <option value="Live">Live</option> </select> <h4>Change a feedback detail</h4> <label htmlFor="detail">Include any specific comments on what should be improved, added, etc.</label> <textarea name="detail" id="detail" value={detail} onChange={handleInputChange} /> <EditFeedbackButtonsContainer> <EditFeedbackButtonDelete onClick={deleteFeedback}> Delete </EditFeedbackButtonDelete> <EditFeedbackButtonCancel onClick={cancelAddFeedback}>Cancel</EditFeedbackButtonCancel> <EditFeedbackButtonAdd onClick={editFeedback}>Edit Feedback</EditFeedbackButtonAdd> </EditFeedbackButtonsContainer> </EditFeedbackFormContainer> ); };
内容的提问来源于stack exchange,提问作者lsokol
相关产品推荐
相关产品推荐

