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

相关推荐
摘星编程16 分钟前
React Native for OpenHarmony 实战:DisplayInfo 显示信息详解
android·react native·react.js
小宇的天下21 分钟前
Calibre 3Dstack --每日一个命令day13【enclosure】(3-13)
服务器·前端·数据库
LongJ_Sir31 分钟前
Cesium--可拖拽气泡弹窗(Vue3版)
javascript
跟着珅聪学java1 小时前
JavaScript 中定义全局变量的教程
javascript
哈哈你是真的厉害1 小时前
React Native 鸿蒙跨平台开发:FlatList 基础列表代码指南
react native·react.js·harmonyos
一只小bit1 小时前
Qt 文件:QFile 文件读写与管理教程
前端·c++·qt·gui
午安~婉1 小时前
整理知识点
前端·javascript·vue
向前V1 小时前
Flutter for OpenHarmony数独游戏App实战:底部导航栏
javascript·flutter·游戏
人道领域2 小时前
JavaWeb从入门到进阶(javaScript)
开发语言·javascript·ecmascript
军军君012 小时前
Three.js基础功能学习十二:常量与核心
前端·javascript·学习·3d·threejs·three·三维