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

复制Reactjs-Popup受控弹窗示例结合useState无法运行,求排查

Reactjs-Popup受控弹窗结合useState失效问题

我复制了Reactjs-Popup官网的受控弹窗示例代码,结合useState使用时弹窗完全没法正常工作,但把所有useState相关代码删掉后,弹窗又能正常运行了。请问我哪里漏了?

我的代码

index.js

import ReactDOM from 'react-dom/client';
import './index.css';
import ControlledPopup from './ControlledPopup';

const test=ReactDOM.createRoot(document.getElementById('popup'));
test.render(ControlledPopup);

ControlledPopup.jsx

import React, { useState } from 'react';
import Popup from 'reactjs-popup';

const ControlledPopup = () => {
  const [open, setOpen] = useState(false);
  const closeModal = () => setOpen(false);
  return (
    <div>
      <button type="button" className="button" onClick={() => setOpen(o => !o)}>
        Controlled Popup
      </button>
      <Popup open={open} closeOnDocumentClick onClose={closeModal}>
        <div className="modal">
          <a className="close" onClick={closeModal}>
            &times;
          </a>
          Lorem ipsum dolor sit amet, consectetur adipisicing elit. Beatae magni
          omnis delectus nemo, maxime molestiae dolorem numquam mollitia, voluptate
          ea, accusamus excepturi deleniti ratione sapiente! Laudantium, aperiam
          doloribus. Odit, aut.
        </div>
      </Popup>
    </div>
  );
};

export default ControlledPopup;

问题原因及解决办法

问题出在index.js的渲染写法上:你直接把组件函数ControlledPopup传给了render方法,而不是以JSX元素的形式渲染它。

React要求函数组件必须以<Component />的形式渲染,否则React不会把它当成组件实例处理,组件内部的hooks(比如useState)就没法正常初始化——因为hooks只能在React组件的渲染流程里调用。

修改index.js里的渲染代码即可:

import ReactDOM from 'react-dom/client';
import './index.css';
import ControlledPopup from './ControlledPopup';

const test=ReactDOM.createRoot(document.getElementById('popup'));
test.render(<ControlledPopup />); // 改成JSX元素形式

这样React会正确创建组件实例,useState就能正常工作,受控弹窗的逻辑也会恢复正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:35:22