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

React模态框中Table的useState状态重置与初始化异常问题

问题分析与解决方案

你的核心问题出在两个关键点:

  1. useState的初始值仅在组件首次挂载时生效一次,后续模态框关闭再打开导致组件重新渲染时,不会自动用updatedIngredients覆盖现有状态。
  2. 关闭模态框时,你把editTableData从数组类型改成了单个对象类型(initialState是单个食材对象),类型不匹配导致后续无法正常同步新数据。

具体修复步骤

1. 修正状态重置的类型匹配

editTableData初始是数组结构,重置时要保持类型一致,改为空数组:

const closeModal = () => {
  handleClose(true)      
  // 重置为空数组,匹配初始状态的数组类型
  setEditTableData([]);
}

2. 每次打开模态框时同步最新数据

添加useEffect监听模态框的show状态,当模态框打开(show变为true)时,自动将editTableData更新为最新的updatedIngredients:

import { useState, useEffect } from "react" // 别忘了导入useEffect

// ... 其他代码 ...

const [editTableData, setEditTableData] = useState(updatedIngredients)

// 监听show状态,打开模态框时同步最新食材数据
useEffect(() => {
  if (show) {
    // 用展开运算符创建新数组,避免引用共享问题
    setEditTableData([...updatedIngredients]);
  }
}, [show, updatedIngredients]) // 依赖项:show或updatedIngredients变化时触发

3. (可选)正确使用Key重置组件

如果想用Key方式重置组件状态,不要每次渲染都生成新的uuidv4()(会导致组件频繁重新挂载,影响性能),应该用和模态框内容绑定的唯一标识,比如modalTitle:

<Modal key={modalTitle} show={show} onHide={closeModal} size="xl">

这样只有当模态框内容(如标题)变化时,组件才会重新挂载,自动用新的updatedIngredients初始化状态。

完整修改后的关键代码片段

import { Form, Modal, Button, Table } from "react-bootstrap"
import { parseIngredient, parseInstruction } from '@jlucaspains/sharp-recipe-parser';
import axios from "axios";
import { v4 as uuidv4 } from "uuid"
import { useState, useEffect } from "react" // 新增useEffect导入

export default function AddRecipeModal( { show, handleClose, modalTitle, modalImage, modalIngredients, modalSteps }) {

const updatedIngredients = modalIngredients.map((modalIngredient) => {
    const parsedIngredient = parseIngredient(modalIngredient.raw, 'en')
    return {
      ...modalIngredient,
      ingredientId: uuidv4(),
      name: parsedIngredient.ingredient,
      unit: parsedIngredient.unit,
      quantity: parsedIngredient.quantity
    }
  });

const [editTableData, setEditTableData] = useState(updatedIngredients)

// 新增:打开模态框时同步最新数据
useEffect(() => {
  if (show) {
    setEditTableData([...updatedIngredients]);
  }
}, [show, updatedIngredients])

const handleSubmit = async (e : any) => {
    try {
      const resp = await axios.post("http://localhost:8000/recipe/add", 
      { title: modalTitle, 
        ingredients: updatedIngredients,
        steps: modalSteps,
        image: modalImage
     })
      handleClose(true)
      console.log(resp.data)
    } catch (error : any) {
      console.log(error.response)
    }
  }

const closeModal = () => {
    handleClose(true)      
    setEditTableData([]); // 重置为空数组,匹配初始类型
}

// ... 其余渲染代码不变 ...

额外说明

  • 你当前表格渲染用的是updatedIngredients,后续恢复编辑功能时,记得把表格数据源改成editTableData,并绑定对应的状态修改逻辑。
  • 用useEffect监听show是最稳妥的方案,无论模态框通过何种方式打开,都能保证状态同步最新数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:02:32