react 通过ref调用子组件的方法

背景

父组件内引入了一个弹窗组件,弹窗组件使用了完全内聚的开发方法;

实现思路

父组件内通过ref获取的子组件,通过current调用子组件的方法,子组件需要通过forwardRef进行"包装"导出,通过useImperativeHandle暴露可以被current使用的方法;

父组件代码

javascript 复制代码
import React, { useState, useRef } from "react";
// 引入组件
import Edit from './component/edit';
export default function Parent() {
  // 定义组件ref
  const editRef = useRef(null);
  /**
   * @method 新建
   * @returns {viod}
   */
  const onCreate = () => {
    // 调用子组件的openModal方法
    editRef.current.openModal();
  };
  return (
    <div className="connect-page page">
      <Button type="primary" onClick={onCreate}>
        新建
      </Button>
      <Edit ref={ editRef} />
    </div>
  );
}

子组件代码

javascript 复制代码
import React, {useState, forwardRef, useImperativeHandle} from 'react';
import {Modal } from 'antd';
function Edit(props, ref) {
  // 定义弹窗状态变量
  const [isModalOpen, setIsModalOpen] = useState(false);
  /**
   * @method 打开弹窗
   * @returns {viod}
   */
  const openModal = () => {
    setIsModalOpen(true);
  };
  /**
   * @method 关闭弹窗
   * @returns {viod}
   */
  const closeModal = () => {
    console.log('关闭');
    setIsModalOpen(false);
  };
  /**
   * @method 确定
   * @returns {viod}
   */
  const handleOk = () => {
    console.log('确定');
    closeModal();
  };
  /**
   * @method 取消
   * @returns {viod}
   */
  const handleCancel = () => {
    console.log('取消');
    closeModal();
  };
  useImperativeHandle(ref, () => {
    return {
      openModal
    }
  });
  return (
    <Modal title="新建" open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
      <p>Some contents...</p>
      <p>Some contents...</p>
      <p>Some contents...</p>
    </Modal>
  )
}
export default forwardRef(Edit);

踩坑

  1. Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

解决方案:子组件使用forwardRef进行"包装"后进行导出;

javascript 复制代码
// 子组件
export default forwardRef(需要导出的组件);
  1. 父组件找不到子组件方法

解决方案:子组件内使用useImperativeHandle对方法进行暴露;

javascript 复制代码
import React, {
  // 其他引入...
  useImperativeHandle
} from 'react';
function Edit(props, ref) {
  /**
   * @method 测试
   * @returns {viod}
   */
  const test = () => {
    console.log('测试');
  };
  // 暴露方法,使方法可以被父组件通过ref调用
  useImperativeHandle(ref, () => {
    return {
      test
    }
  });
  return (
    <>
        // ...
    </>
  )
}
export default forwardRef(Edit);
相关推荐
2301_818732061 分钟前
下载nvm后,通过nvm无法下载node,有文件夹但是为空 全局cmd,查不到node和npm 已解决
前端·npm·node.js
赵民勇2 分钟前
JavaScript中的this详解(ES5/ES6)
前端·javascript·es6
hhcccchh3 分钟前
学习vue第九天 计算属性与侦听器
前端·vue.js·学习
wayne2144 分钟前
React Native 状态管理方案全梳理:Redux、Zustand、React Query 如何选
javascript·react native·react.js
我的golang之路果然有问题5 分钟前
Mac 上的 Vue 安装和配置记录
前端·javascript·vue.js·笔记·macos
代码游侠9 分钟前
应用——Linux FrameBuffer图形显示与多线程消息系统项目
linux·运维·服务器·开发语言·前端·算法
小二·17 分钟前
Python Web 开发进阶实战:Flask 项目中的表单验证、错误处理与用户体验优化
前端·python·flask
天荒地老笑话么17 分钟前
IntelliJ IDEA 运行 Tomcat 报错:Please, configure Web Facet first!
java·前端·tomcat·intellij-idea
王五周八18 分钟前
html转化为base64编码的pdf文件
前端·pdf·html
神色自若21 分钟前
vue3 带tabs的后台管理系统,切换tab标签后,共用界面带参数缓存界面状态
前端·vue3