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

如何在React动态模态框中使用State Hook 解决取值异常及按钮不显示问题

问题原因及解决方案

第一个问题根因

  • 你错误将按钮渲染函数存入了state,state中存储的是首次组件渲染时生成的modalButtonsPreSubmit函数,该函数的闭包始终捕获首次渲染时的tmpName初始值undefined,后续tmpName更新后,state中存储的旧函数闭包不会同步更新,因此无法拿到最新的tmpName值,这不属于state上下文特性,是使用姿势错误导致的。
  • 额外语法问题:代码中Form.Control的defaultValue=name存在错误,name变量未定义。

第二个问题根因

  • 混淆了submitted状态的类型:初始定义为布尔值,提交时却把modalButtonsPostSubmit函数赋值给了它,导致条件判断逻辑完全异常。
  • 你将按钮渲染函数直接放在JSX中渲染,没有手动执行函数生成JSX元素,React不会自动调用函数渲染内容,因此没有按钮显示。

正确实现

不要将渲染函数/JSX存入state,直接通过布尔状态控制按钮渲染即可,修正后的完整代码如下:

import { useState } from 'react';
import { Table, Form, Button, Modal } from 'react-bootstrap';

const System = () => {
  const [tmpName, setTmpName] = useState('');
  const [showName, setShowName] = useState(false);
  const [submitted, setSubmitted] = useState(false);
  // 实际业务中可替换为你从接口/全局状态获取的名称值
  const [name, setName] = useState('初始名称');

  const handleClose = () => {
    setShowName(false);
    // 关闭模态框时重置状态,下次打开恢复初始样式
    setSubmitted(false);
    setTmpName('');
  }

  const handleCancel = () => {
    setShowName(false);
    setSubmitted(false);
    setTmpName('');
  };

  const handleSetNameSubmit = () => {
    console.log('tmpName: ', tmpName);
    // 执行名称修改逻辑,比如调用接口更新
    setName(tmpName);
    // 切换为提交后状态,显示关闭按钮
    setSubmitted(true);
  }

  return (
    <>
      <div className="card">
        <h5>System</h5>
        <Table variant="dark" responsive>
          <tr>
            <td>Name:</td>
            <td>{name} <Button onClick={() => setShowName(true)}>Edit</Button></td>
          </tr>
        </Table>
      </div>

      {/* 设置名称模态框 */}
      <Modal show={showName} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Set Name</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          <span>
            <Form.Control
              type="text"
              defaultValue={name}
              onChange={(event) => setTmpName(event.target.value)}
            />
          </span>
        </Modal.Body>
        <Modal.Footer>
          {/* 直接根据submitted状态条件渲染按钮 */}
          {!submitted ? (
            <>
              <Button variant="secondary" onClick={handleCancel}>
                取消
              </Button>
              <Button variant="primary" onClick={handleSetNameSubmit}>
                提交
              </Button>
            </>
          ) : (
            <Button variant="secondary" onClick={handleClose}>
              关闭
            </Button>
          )}
        </Modal.Footer>
      </Modal>
    </>
  )
}

export default System;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:15:03