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

React+Redux开发多内容模态框无法分别打开问题求解

问题根因

你当前的Redux全局只存储了一个布尔类型的isModalOpen状态,所有Modal组件都读取同一个状态值,只要状态为true,页面内所有Modal会同时渲染,无法区分不同模态框的开关状态,这就是第二个模态框功能失效的原因。

修改方案

我们把Redux存储的模态框状态从布尔值改为当前激活的模态框唯一标识,通过id匹配控制对应模态框的展示:

1. 修改Redux相关逻辑(action和reducer)

首先调整action的传参,以及reducer的存储结构:

action/index.js

// 原来的isModalOpen action修改为接收模态框id,传null代表关闭所有模态框
export const setActiveModal = (modalId) => {
  return {
    type: 'SET_ACTIVE_MODAL',
    payload: modalId
  }
}

reducer/index.js

const initialState = {
  activeModal: null // 初始值为null,代表没有模态框打开
}

const rootReducer = (state = initialState, action) => {
  switch(action.type) {
    case 'SET_ACTIVE_MODAL':
      return {
        ...state,
        activeModal: action.payload
      }
    default:
      return state
  }
}

export default rootReducer

2. 修改Modal.js组件

给组件新增modalId属性,只有Redux中存储的激活id和当前组件id匹配时才渲染,同时补充阻止事件冒泡逻辑,避免点击模态框内容时误触发关闭:

import React from 'react';
import './Modal.css';
import {useSelector, useDispatch} from 'react-redux';
import { setActiveModal } from '../actions/index';

// 组件接收modalId作为必填参数
const Modal = (props) => {
    const dispatch = useDispatch();
    const activeModal = useSelector(state => state.activeModal);

    const closeModal = () => {
        dispatch(setActiveModal(null));
    }
    // 只有当前激活id和组件id匹配时才渲染
    if(activeModal !== props.modalId) return null;
    
    return(
        <div id="modal-container" onClick={closeModal}>
            <div id="modal" onClick={(e) => e.stopPropagation()}>
                <span onClick={closeModal}>Close</span>
                <h2>Modal</h2>
                <p>description</p>
                {props.children}
            </div>
        </div>
    );
}

export default Modal;

3. 修改App.js

给两个Modal分别传入唯一id,打开模态框时dispatch对应id即可:

import React from 'react';
import { useDispatch} from 'react-redux';
import Modal from './Modals/Modal';
import Contents1 from './Modals/Contents1';
import Contents2 from './Modals/Contents2';
import { setActiveModal } from './actions/index';

import './App.css';

const App =  () => {

  const dispatch = useDispatch();

  const openModal1 = () => {
    dispatch(setActiveModal('modal1')); 
  };

  const openModal2 = () => {
    dispatch(setActiveModal('modal2'));
  };

  return (
    <div>
      <button onClick={openModal1}>Open Modal 1</button>     
      <Modal modalId="modal1">
        <Contents1 />
      </Modal>

      <button onClick={openModal2}>Open Modal 2</button>
      <Modal modalId="modal2">
        <Contents2 />
      </Modal>
    </div>
  );
}

export default App;

后续如果要新增更多模态框,只需要给新Modal设置唯一id,打开时dispatch对应id即可,扩展性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:27:03