当前位置: 首页 > news >正文

React通过命令式的弹窗控制,实现组件封装

在 React 18 中,通过 ref.current?.open(‘create’) 实现组件封装是一种命令式的控制方式。这种方式的核心思想是将组件的内部逻辑(如打开、关闭)封装在组件内部,并通过 ref 暴露给父组件调用。以下是详细的实现步骤:

  1. 封装组件
    使用 forwardRef 和 useImperativeHandle 将组件的内部方法(如 open)暴露给父组件。

示例代码:

import React, { useRef, useImperativeHandle, forwardRef, useState } from 'react';
import './MyComponent.css'; // 组件样式

const MyComponent = forwardRef((props, ref) => {
  const [isOpen, setIsOpen] = useState(false);
  const [mode, setMode] = useState(''); // 用于区分模式,如 'create'

  // 暴露 open 方法给父组件
  useImperativeHandle(ref, () => ({
    open: (mode) => {
      setMode(mode);
      setIsOpen(true);
    },
    close: () => {
      setIsOpen(false);
    },
  }));

  if (!isOpen) return null;

  return (
    <div className="component-overlay">
      <div className="component-content">
        <button className="component-close" onClick={() => setIsOpen(false)}>
          &times;
        </button>
        {mode === 'create' && <CreateForm />}
        {mode === 'edit' && <EditForm />}
      </div>
    </div>
  );
});

// 示例表单组件
const CreateForm = () => (
  <div>
    <h2>创建模式</h2>
    <form>
      <input type="text" placeholder="输入内容" />
      <button type="submit">提交</button>
    </form>
  </div>
);

const EditForm = () => (
  <div>
    <h2>编辑模式</h2>
    <form>
      <input type="text" placeholder="编辑内容" />
      <button type="submit">保存</button>
    </form>
  </div>
);

export default MyComponent;
  1. 在父组件中使用
    父组件通过 useRef 获取组件的引用,并调用 ref.current?.open(‘create’) 打开组件。

示例代码:

import React, { useRef } from 'react';
import MyComponent from './MyComponent';

function App() {
  const componentRef = useRef(null);

  const handleOpenCreate = () => {
    componentRef.current?.open('create'); // 打开创建模式
  };

  const handleOpenEdit = () => {
    componentRef.current?.open('edit'); // 打开编辑模式
  };

  return (
    <div>
      <button onClick={handleOpenCreate}>打开创建模式</button>
      <button onClick={handleOpenEdit}>打开编辑模式</button>

      <MyComponent ref={componentRef} />
    </div>
  );
}

export default App;
  1. 样式文件 MyComponent.css
    确保组件的样式正确:
.component-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
}

.component-content {
  background-color: white;
  padding: 20px;
  border-radius: 8px;
  position: relative;
  max-width: 500px;
  width: 100%;
}

.component-close {
  position: absolute;
  top: 10px;
  right: 10px;
  background: none;
  border: none;
  font-size: 20px;
  cursor: pointer;
}
  1. 实现原理
    forwardRef:将 ref 传递给子组件。

useImperativeHandle:在子组件中暴露方法(如 open 和 close)给父组件。

命令式调用:父组件通过 ref.current?.open(‘create’) 控制组件的显示。
5. 支持更多功能
动态内容:可以通过 open 方法传递更多参数,动态渲染内容。

关闭回调:在 close 方法中添加回调函数,处理关闭后的逻辑。

动画效果:结合 react-transition-group 实现动画。

示例:动态内容

useImperativeHandle(ref, () => ({
  open: (mode, data) => {
    setMode(mode);
    setData(data); // 设置动态数据
    setIsOpen(true);
  },
}));
  1. 总结
    通过 useRef 和 useImperativeHandle,可以实现命令式的组件控制,使父组件能够直接调用组件的 open 和 close 方法。这种方式非常适合需要动态控制组件显示的场景,代码结构清晰且易于维护。

相关文章:

  • 选项模式(Options Pattern)
  • QT系列教程(22) QT 实现电子相册(一)--目录树和向导
  • AS_Path过滤器应用灵活配置示例
  • Linux驱动开发-设备树
  • python之使用scapy扫描本机局域网主机,输出IP/MAC表
  • OpenHarmony体系架构深度解析
  • Three.js 进阶(灯光阴影关系和设置、平行光、阴影相机)
  • Vue动态组件完全指南:原理、使用场景与最佳实践
  • 消防设施操作员考试:用故事开启高效备考之旅​
  • 数据分析项目:直播电商用户流失分析
  • 微信小程序面试内容整理-生命周期函数
  • Mamba| Miniforge3 安装和配置
  • 【Python 数据结构 14.邻接表】
  • 【鸿蒙开发】Hi3861学习笔记- GPIO之LED
  • Excel中国式排名,3种方法!
  • b站视频下载工具软件怎么下载
  • const_cast
  • c++ 中的引用
  • Jenkins链接私有仓库Failed to connect to repository,stderr: No ECDSA...的问题
  • 英语学习(GitHub学到的分享)
  • 篮球培训机构东方启明星被指停摆,家长称已登记未退费用超百万
  • 技术派|威胁F-35、击落“死神”,胡塞武装防空战力如何?
  • 习近平就乌拉圭前总统穆希卡逝世向乌拉圭总统奥尔西致唁电
  • 巴菲特最新调仓:一季度大幅抛售银行股,再现保密仓位
  • 中国社联成立95周年,《中国社联期刊汇编》等研究丛书出版
  • 阿联酋与美国达成超过2000亿美元协议