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

React表单页面重载时useState初始化表单数据丢失问题

问题根源

这是React useState 初始化机制的典型误用:

  • useState 接收的初始参数仅在组件首次挂载时生效一次,后续组件重渲染不会重新计算初始值
  • 从列表页跳转进入表单时,全局Context中的declas列表已经完成接口请求,组件初始化执行declas?.find(...)可以直接拿到对应申报数据,因此所有表单state初始化正常,页面展示无问题
  • 刷新页面/直接通过链接访问时:
    1. 组件首次挂载阶段,Context内的declas还未完成请求为空,declas?.find(...)返回undefined,所有表单state被初始化为空值/默认值
    2. 被注释的useEffect即使后续请求到了完整申报数据,也仅调用了setDecla更新decla这一个state,其余event/owner/content等表单字段对应的state没有同步更新,自然无法展示数据
    3. 代码中react-select组件使用的defaultValue属性同样仅在组件首次挂载时生效,后续对应state更新也不会触发组件重新渲染选中值,进一步导致数据不显示。
修复步骤

1. 完善数据请求逻辑

放开被注释的useEffect,拿到接口返回的申报数据后,同步更新所有表单关联的state,不要仅更新decla:

useEffect(() => {
  const fetchData = async () => {
    await GET();
    const resData = await GET_decla(id);
    if (!resData) return;
    setDecla(resData);
    // 同步给所有表单state赋值
    setEvent(resData.event);
    setOwner(resData.owner ?? user.lid_id);
    setContent(resData.content ?? "");
    setTotal(resData.total ?? 0);
    setReceipt(resData.receipt);
    setBoekstuk(resData.boekstuk ?? "");
    setContent_ficus(resData.content_ficus ?? "");
    setDefaultValues(
      resData.present?.map(pres => optionsLeden?.find(opt => opt.value === pres)) || []
    );
  };
  fetchData();
  // eslint-disable-next-line
}, [id]);

2. 修正react-select的受控属性

将所有react-select/CreatableSelect组件的defaultValue属性替换为value,保证state更新时组件能同步渲染最新值:

// 成员选择器
<Select
  value={optionsLeden?.find(x => x.value === owner)}
  options={optionsLeden?.filter(x => !["all", 19900].includes(x.value))}
  name="owner"
  id="id_present"
  onChange={e => setOwner(e.value)}
/>

// 活动选择器
<Select
  value={optionsEvents?.find(x => x.value === event?.id)}
  options={optionsEvents}
  name="event"
  onChange={e => setEvent(e.value)}
/>

// 记账科目选择器
<CreatableSelect
  value={optionsBoekstuk?.find(x => x.value === boekstuk)}
  options={optionsBoekstuk}
  name="boekstuk"
  id="id_boekstuk"
  onCreateOption={createBookstuk}
  onChange={e => setBoekstuk(e.value)}
/>

优化建议

当前表单拆分了8个独立的useState,后续维护很容易出现更新遗漏的问题,建议要么用单个useState统一管理整个表单对象,要么直接使用react-hook-form这类专门的表单库,降低状态同步的心智负担。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 05:36:25