React18函数组件实现ref获取dom实例

一、需求场景:父组件想要调用子组件的方法,状态

例:在图中,当我点击 修改按钮时,弹出编辑框。底层的列表为父组件,上面的弹出框为子组件

二、实现方法: 

1.第一步:父组件中使用useRef定义ref,并绑定在子组件身上

//引入useRef函数
import {React,useEffect,useRef,useState} from 'react'; 
//定义ref
const editorRef=useRef()
//在子组件身上绑定
<Editor  ref={editorRef}></Editor>

2.第二步(核心步骤):子组件中forwardRef+useImperativeHandle hook函数把方法暴露出去

核心api:

(1)forwardRef((props,ref) => {})

是React 中用于转发 ref 到子组件的函数。通过使用 forwardRef,父组件可以获取子组件实例的引用,并直接操作子组件的 DOM 节点或调用子组件的方法。

(props, ref) => {} 是一个函数组件的定义,通过 forwardRef 包裹后,这个函数组件就具备了能够接收 ref 的能力。当父组件将 ref 传递给这个包裹后的函数组件时,父组件就可以访问到子组件的实例。

(2)useImperativeHandle(ref, createHandle, [deps]) 

有3个参数

  • ref:对子组件暴露的引用,通常是通过 useRef 创建的。
  • createHandle:一个函数,用来创建暴露给父组件的方法或属性。
  • [deps]:可选的依赖数组,类似于 useEffect 中的依赖数组,当依赖数组中的值发生变化时,会重新创建暴露给父组件的方法或属性。

例:useImperativeHandle(ref, () => ({
        show: (record) => {
            setishow(true);
            setformdata(record)
            console.log(record)
        },
      }));

const Editor = forwardRef((props,ref) => {
  const [formdata,setformdata]=useState({  
    name: '',
    age: '',
    address: ''})
    const [ishow,setishow] = useState(false)
    useImperativeHandle(ref, () => ({
        show: (record) => {
            setishow(true);
            setformdata(record)
            console.log(record)
        },
      }));
    const handleOk=()=>{

    }
    const handleCancel=()=>{
        setishow(false)
    }
    const onFinish = (values) => {
        console.log('Success:', values);
      };
    const onFinishFailed = (errorInfo) => {
        console.log('Failed:', errorInfo);
      };
    return(
        <Modal
        title="编辑"
        open={ishow}
        onOk={handleOk}
        onCancel={handleCancel}
      >
  <Form
    name="basic"
    labelCol={{
      span: 8,
    }}
    wrapperCol={{
      span: 16,
    }}
    style={{
      maxWidth: 600,
    }}
    initialValues={formdata}
    onFinish={onFinish}
    onFinishFailed={onFinishFailed}
    autoComplete="off"
  >
    <Form.Item
      label="姓名"
      name="name"
      rules={[
        {
          required: true,
          message: 'Please input your username!',
        },
      ]}
    >
      <Input />
      </Form.Item>

      <Form.Item
      label="年龄"
      name="age"
      rules={[
        {
          required: true,
          message: 'Please input your username!',
        },
      ]}
    >
      <Input />
      </Form.Item>

      <Form.Item
      label="地址"
      name="address"
      rules={[
        {
          required: true,
          message: 'Please input your username!',
        },
      ]}
    >
      <Input />
    </Form.Item>
  </Form>
     </Modal>)
});
export default Editor;

3.父组件中调用子ref方法

  editorRef.current.show(record)  还可以传递参数

  const edit = (text, record) => {
   editorRef.current.show(record)
  };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值