react 封装弹框组件 传递数据

当我们使用react 开发 封装组件 肯定涉及 子向父传值

我们来直接上代码

来一个子组件

方式一:通过回调函数(最常用)

复制代码
import React from 'react'
import { Modal } from 'antd'

const CreateModal = (props) => {
  const {
    modalVisible,
    onSubmit,
    onCancel,
    title = "添加图书",
    children,
    okText = "确定",
    cancelText = "取消",
    width = 520,
    ...restProps
  } = props

  // 子组件内部的处理函数
  const handleSubmit = () => {
    // 子组件准备要传递的数据
    const childData = {
      message: "这是子组件的数据",
      timestamp: new Date().getTime(),
      customField: "自定义字段"
    }

    // 调用父组件传递的回调函数,并传递数据
    onSubmit(childData)
  }

  const handleCancel = () => {
    const cancelData = {
      reason: "用户取消",
      time: new Date().toLocaleString()
    }
    onCancel(cancelData)
  }

  return (
    <Modal
      title={title}
      open={modalVisible}
      onOk={handleSubmit}
      onCancel={handleCancel}
      okText={okText}
      cancelText={cancelText}
      width={width}
      {...restProps}
    >
      {children || (
        <div>
          <p>这里是默认内容</p>
          <p>你可以通过 children 属性传入自定义内容</p>
        </div>
      )}
    </Modal>
  )
}

export default CreateModal

其实我认为这个 父向子 传值 传方法 其实相对来说 比 vue 好理解 相对来说

复制代码
  onSubmit(childData)

当我们点击确定的时候 就可以 传值 给父组件。父组件绑定这个数据 就好了

复制代码
<CreateModal
        modalVisible={modalVisible}
        onSubmit={handleSubmit}
        onCancel={handleCancel}
        title="自定义标题"
      >
        {/* 自定义内容 */}
        <div>这是自定义的弹窗内容</div>
      </CreateModal>

  const [modalVisible, setModalVisible] = useState(false)
  const openModal = () => {
    setModalVisible(true)
  }

  const handleSubmit = (e) => {
    console.log(e, "e")


  }
  const handleCancel = () => {

  }

方式二:使用 forwardRef + useImperativeHandle

子组件

复制代码
import React, { forwardRef, useImperativeHandle } from 'react'
import { Modal } from 'antd'

const CreateModal = forwardRef((props, ref) => {
  const {
    modalVisible,
    onSubmit,
    onCancel,
    title = "添加图书",
    children,
    okText = "确定",
    cancelText = "取消",
    width = 520,
    ...restProps
  } = props

  // 暴露给父组件的方法
  useImperativeHandle(ref, () => ({
    // 子组件的方法,父组件可以通过 ref 调用
    getChildData: () => {
      return {
        message: "来自子组件的数据",
        data: "其他数据"
      }
    },
    
    // 子组件的其他方法
    validateForm: () => {
      // 表单验证逻辑
      return true
    }
  }))

  const handleSubmit = () => {
    onSubmit()
  }

  const handleCancel = () => {
    onCancel()
  }

  return (
    <Modal
      title={title}
      open={modalVisible}
      onOk={handleSubmit}
      onCancel={handleCancel}
      okText={okText}
      cancelText={cancelText}
      width={width}
      {...restProps}
    >
      {children}
    </Modal>
  )
})

export default CreateModal

父组件使用

复制代码
import React, { useState, useRef } from 'react'
import { Button } from 'antd'
import CreateModal from './CreateModal'

const ParentComponent = () => {
  const [modalVisible, setModalVisible] = useState(false)
  const modalRef = useRef()

  const handleSubmit = () => {
    // 通过 ref 获取子组件数据
    const childData = modalRef.current?.getChildData()
    console.log('子组件数据:', childData)
    
    // 验证表单
    const isValid = modalRef.current?.validateForm()
    if (isValid) {
      setModalVisible(false)
    }
  }

  const handleCancel = () => {
    setModalVisible(false)
  }

  return (
    <div>
      <Button onClick={() => setModalVisible(true)}>
        打开弹窗
      </Button>
      
      <CreateModal
        ref={modalRef}
        modalVisible={modalVisible}
        onSubmit={handleSubmit}
        onCancel={handleCancel}
      />
    </div>
  )
}

方式三:使用 Context(适合深层嵌套)

子组件

复制代码
import React, { createContext, useContext, useState } from 'react'
import { Modal } from 'antd'

// 创建 Context
const ModalContext = createContext()

const CreateModal = (props) => {
  const {
    modalVisible,
    onSubmit,
    onCancel,
    title = "添加图书",
    children,
    okText = "确定",
    cancelText = "取消",
    width = 520,
    ...restProps
  } = props

  const [modalData, setModalData] = useState({})

  const handleSubmit = () => {
    // 传递数据给父组件
    onSubmit(modalData)
  }

  return (
    <ModalContext.Provider value={{ modalData, setModalData }}>
      <Modal
        title={title}
        open={modalVisible}
        onOk={handleSubmit}
        onCancel={onCancel}
        okText={okText}
        cancelText={cancelText}
        width={width}
        {...restProps}
      >
        {children}
      </Modal>
    </ModalContext.Provider>
  )
}

// 在子组件内部使用
const ModalContent = () => {
  const { setModalData } = useContext(ModalContext)
  
  const handleInputChange = (e) => {
    setModalData(prev => ({
      ...prev,
      inputValue: e.target.value
    }))
  }

  return (
    <div>
      <input onChange={handleInputChange} placeholder="输入内容" />
    </div>
  )
}

export { CreateModal, ModalContent }

总结

  • 方式一(回调函数):最常用,适合大多数场景

  • 方式二(forwardRef):适合需要调用子组件方法的场景

  • 方式三(Context):适合深层嵌套组件通信

推荐使用方式一,因为它最符合 React 的数据流理念,代码清晰易懂。

相关推荐
大怪v1 分钟前
【Virtual World 03】上帝之手
前端·javascript
招来红月2 小时前
记录JS 实用API
javascript
别叫我->学废了->lol在线等2 小时前
演示 hasattr 和 ** 解包操作符
开发语言·前端·python
霍夫曼2 小时前
UTC时间与本地时间转换问题
java·linux·服务器·前端·javascript
DARLING Zero two♡2 小时前
浏览器里跑 AI 语音转写?Whisper Web + cpolar让本地服务跑遍全网
前端·人工智能·whisper
꒰ঌ小武໒꒱2 小时前
文件上传全维度知识体系:从基础原理到高级优化
javascript·node.js
Lovely Ruby3 小时前
前端er Go-Frame 的学习笔记:实现 to-do 功能(三),用 docker 封装成镜像,并且同时启动前后端数据库服务
前端·学习·golang
深红3 小时前
玩转小程序AR-实战篇
前端·微信小程序·webvr
银空飞羽3 小时前
让Trae SOLO全自主学习开发近期爆出的React RCE漏洞靶场并自主利用验证(CVE-2025-55182)
前端·人工智能·安全
钮钴禄·爱因斯晨3 小时前
DevUI 组件生态与 MateChat 智能应用:企业级前端智能化实战
前端