You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用react-router在React.js中实现编辑表单回显与更新

解决React编辑表单初始化问题

要实现用路由传递的联系人数据初始化编辑表单,需对自定义useInput钩子和EditForm组件做以下修改:

1. 修改useInput钩子,支持初始值

当前钩子的enteredValue默认初始化为空字符串,我们需要让它接收外部传入的初始值,以此实现用路由数据初始化表单。

修改后的useInput代码:

import { useState } from "react";

const useInput = (validateValue, initialValue = '') => {
  const [enteredValue, setEnteredValue] = useState(initialValue)
  const [isTouched, setIsTouched] = useState(false)

  const valueIsValid = validateValue(enteredValue);
  const hasError = !valueIsValid && isTouched;

  const valueChangeHandler = (e) => {
    setEnteredValue(e.target.value)
  }

  const InputBlurHandler = (e) => {
    setIsTouched(true)
  }

  const reset = () => {
    setEnteredValue('');
    setIsTouched(false)
  }
   
  return {
    value: enteredValue, 
    isValid: valueIsValid,
    hasError, 
    valueChangeHandler, 
    InputBlurHandler,
    reset
  }
};

export default useInput;

修改点:

  • 给useInput新增第二个参数initialValue,默认值为空字符串
  • 初始化enteredValue时使用initialValue代替硬编码的''

2. 在EditForm中用路由数据初始化表单字段

在EditForm组件中,从location.state拿到联系人数据后,将每个字段的值作为初始值传入对应的useInput调用,同时处理数据为空的边界情况(比如用户直接访问编辑页面)。

修改后的EditForm关键部分代码:

import React from 'react'
import useInput from '../formHooks/hooks/use-input'
import './EditForm.css'
import LoadingSpinner from './LoadingSpinner'
import {useLocation} from 'react-router-dom'

const EditForm = (props) => {
  const location = useLocation();
  const data = location.state || {}; // 处理数据为空的情况

  // 用data中的对应字段作为初始值传入useInput
  const {
    value: enteredFirstName,
    isValid: enteredFirstNameIsValid,
    hasError: firstNameInputHasError,
    InputBlurHandler: firstNameBlurHandler,
    valueChangeHandler: firstNameChangedHandler,
    reset: resetFirstNameInput
  } = useInput(value => value.trim() !== "", data.firstName || '')
     
  const {
    value: enteredLastName,
    isValid: enteredLastNameIsValid,
    hasError: lastNameInputHasError,
    InputBlurHandler: lastNameBlurHandler,
    valueChangeHandler: lastNameChangedHandler,
    reset: resetLastNameInput
  } = useInput(value => value.trim() !== "", data.lastName || '')
    
  const {
    value: enteredEmail,
    isValid: enteredEmailIsValid,
    hasError: emailInputHasError,
    InputBlurHandler: emailBlurHandler,
    valueChangeHandler: emailChangedHandler,
    reset: resetEmailInput
  } = useInput(value => value.includes('@'), data.email || '')

  const {
    value: enteredPhoneNumber,
    isValid: enteredPhoneNumberIsValid,
    hasError: phoneNumberInputHasError,
    InputBlurHandler: phoneNumberBlurHandler,
    valueChangeHandler: phoneNumberChangedHandler,
    reset: resetPhoneNumberInput
  } = useInput(value => value.trim() !== "", data.phone || '')

  const {
    value: enteredAddress1,
    isValid: enteredAddress1IsValid,
    hasError: address1InputHasError,
    InputBlurHandler: address1BlurHandler,
    valueChangeHandler: address1ChangedHandler,
    reset: resetAddress1Input
  } = useInput(value => value.trim() !== "", data.address1 || '')

  const {
    value: enteredAddress2,
    valueChangeHandler: address2ChangedHandler,
    reset: resetAddress2Input
  } = useInput(value => value.trim() == "", data.address2 || '')

  const {
    value: enteredState,
    valueChangeHandler: stateChangedHandler,
    reset: resetStateInput
  } = useInput(value => value.trim() == "", data.state || '')

  const {
    value: enteredCountry,
    valueChangeHandler: countryChangedHandler,
    reset: resetCountryInput
  } = useInput(value => value.trim() == "", data.country || '')

  const {
    value: enteredAbout,
    isValid: enteredAboutIsValid,
    hasError: aboutInputHasError,
    InputBlurHandler: aboutBlurHandler,
    valueChangeHandler: aboutChangedHandler,
    reset: resetAboutInput
  } = useInput(value => value.trim() !== "", data.about || '')

  // 文件输入框(type="file")无法通过value属性初始化,若需展示已上传文件,可额外添加状态显示文件名或预览图

  // 其余代码保持不变...
}

export default EditForm

修改点:

  • 将const data = location.state;改为const data = location.state || {};,避免数据为空时触发报错
  • 每个useInput调用都添加第二个参数,传入data中对应的字段值,用|| ''处理字段不存在的情况

3. 额外注意事项

  • 确保路由配置正确,/edit/:id路由对应的组件为EditForm
  • 提交表单时需传递联系人id,方便后端定位要更新的数据,可在formSubmitHandler中修改:
props.onSaveContact({
  id: data.id, // 添加id字段
  firstName: enteredFirstName,
  lastName: enteredLastName,
  email: enteredEmail,
  phone: enteredPhoneNumber,
  address1: enteredAddress1,
  address2: enteredAddress2,
  state: enteredState,
  country: enteredCountry,
  file: enteredFile,
  about: enteredAbout
})

内容的提问来源于stack exchange,提问作者Duke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 11:55:18