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 的数据流理念,代码清晰易懂。

相关推荐
子兮曰4 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰4 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万4 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝4 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁4 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄4 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95274 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大4 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师4 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端