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

相关推荐
2501_9261028612 小时前
深入浅出Vue.js前端框架设计:核心原理与实践指南
前端·vue.js·前端框架
程序员黑豆13 小时前
使用AI编程开发鸿蒙应用:从环境搭建到实战示例
前端·harmonyos
程序员黑豆16 小时前
鸿蒙应用开发:一次开发多端部署之响应式布局完全指南
前端·harmonyos
小月土星17 小时前
2.0 React Router 前端路由深度解析:从传统后端路由到现代 SPA 的完整演进
前端
To_OC18 小时前
LC 35 搜索插入位置:二分查找谁都会,边界条件谁写谁懵
javascript·算法·leetcode
码哥DFS18 小时前
二叉树的直径
开发语言·javascript·算法
烬羽19 小时前
上来就用 useState?你大概率用错了——useRef 的三种正确打开方式
react.js·前端框架·全栈
badhope33820 小时前
当所有AI都在抄同一份作业:前端模板的趋同、困局与破局
前端·ai·ai编程·前端开发·tailwind·ui设计
光影少年20 小时前
RN的Fabric 渲染流程
运维·前端·javascript·react native·react.js·fabric
烬羽21 小时前
《React Router 受保护路由的 3 个坑,第 2 个 90% 的人都踩过》
react.js·性能优化·全栈