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

react-modal 异常问题排查:多模态框内容显示错误

解决React Modal复用多个实例时内容固定显示最后一个值的问题

嘿,我明白你遇到的麻烦了——点击第一个按钮打开模态框,结果显示的却是第二个的hint值"banana",对吧?这个问题的核心原因很简单:你所有的HintModal实例都共享了App组件里的同一个modalIsOpen状态和hint值。

当你点击第一个按钮时,App的state会把modalIsOpen设为true,同时hint设为"mango"。但此时两个HintModal里的Modal组件都会因为isOpen={this.state.modalIsOpen}而处于激活状态,而React在渲染多个相同组件时,会复用DOM元素,最后渲染的那个Modal(也就是第二个,hint为"banana"的)就会覆盖掉第一个的内容,所以你看到的永远是最后一个的hint。

下面给你两种解决方案,按需选择:

方案一:让每个模态框独立管理自己的状态

这是最简单的解决方式,把状态从父组件App下移到HintModal内部,让每个模态框自己控制是否打开,这样它们之间就不会互相干扰了。

修改你的hintModal.jsx:

import React, { useState } from 'react';
import Modal from 'react-modal';

const HintModal = ({ hint }) => {
  // 每个模态框自己维护打开状态
  const [modalIsOpen, setModalIsOpen] = useState(false);

  const openModal = () => {
    setModalIsOpen(true);
  };

  const closeModal = () => {
    setModalIsOpen(false);
  };

  return (
    <React.Fragment>
      <button onClick={openModal}>Open Modal</button>
      <Modal 
        isOpen={modalIsOpen} 
        onRequestClose={closeModal} 
        contentLabel="Hint Modal"
      >
        <h2>Hint</h2>
        <p>{hint}</p>
        <button onClick={closeModal}>Close</button>
      </Modal>
      <p>We should see: {hint}</p>
    </React.Fragment>
  );
};

export default HintModal;

然后简化App.js,去掉共享的state:

import React, { Component } from 'react';
import HintModal from './hintModal';
import Modal from 'react-modal';
import './App.css';

Modal.setAppElement('#root');

class App extends Component {
  render() {
    return (
      <React.Fragment>
        <h1>Modal Test</h1>
        <h2>First Modal</h2>
        <HintModal hint="mango" />
        <hr />
        <h2>Second Modal</h2>
        <HintModal hint="banana" />
      </React.Fragment>
    );
  }
}

export default App;

方案二:在父组件统一管理多个模态框的状态

如果你需要在父组件里统一控制所有模态框(比如做一个全局关闭按钮),可以给每个模态框分配唯一标识,用对象来管理每个模态框的打开状态:

修改App.js的状态和方法:

import React, { Component } from 'react';
import HintModal from './hintModal';
import Modal from 'react-modal';
import './App.css';

Modal.setAppElement('#root');

class App extends Component {
  // 用对象存储每个模态框的打开状态,键是唯一标识
  state = { 
    modals: {
      mangoModal: false,
      bananaModal: false
    }
  };

  openModal = (modalKey) => {
    this.setState(prevState => ({
      modals: {
        ...prevState.modals,
        [modalKey]: true
      }
    }));
  };

  closeModal = (modalKey) => {
    this.setState(prevState => ({
      modals: {
        ...prevState.modals,
        [modalKey]: false
      }
    }));
  };

  render() {
    return (
      <React.Fragment>
        <h1>Modal Test</h1>
        <h2>First Modal</h2>
        <HintModal 
          modalIsOpen={this.state.modals.mangoModal} 
          openModal={() => this.openModal('mangoModal')} 
          closeModal={() => this.closeModal('mangoModal')} 
          hint="mango" 
        />
        <hr />
        <h2>Second Modal</h2>
        <HintModal 
          modalIsOpen={this.state.modals.bananaModal} 
          openModal={() => this.openModal('bananaModal')} 
          closeModal={() => this.closeModal('bananaModal')} 
          hint="banana" 
        />
      </React.Fragment>
    );
  }
}

export default App;

hintModal.jsx保持你原来的代码即可,不需要修改。

这样每个模态框的打开状态都是独立的,点击第一个按钮只会打开对应hint的模态框,不会出现内容被覆盖的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:55:24