How to use useImperativeHandle of react+Hooks?

use of ref

Ordinary class components have instances, so you can use React.createRef() to mount to a node or component, and then get the node or component through this.

class RefTest extends React.Component{
    constructor(props){
        super(props);
        this.myRef=React.createRef();
    }
    componentDidMount(){
        console.log(this.myRef.current);
    }
    render(){
        return <input ref={this.myRef}/>
    }
}

The use of useImperativeHandle

useImperativeHandle allows you to customize the instance value exposed to the parent component when using ref. In most cases, imperative code like ref should be avoided. useImperativeHandle should be used together with forwardRef.

 Introduction to useImperativeHandle

useImperativeHandle(ref, createHandle, [deps])
  • Only specific operations can be exposed through useImperativeHandle
    • Through the Hook of useImperativeHandle, the ref passed in by the parent component and the object returned by the second parameter of useImperativeHandle are bound together
    • So in the parent component, when inputRef.current is called, it is actually the returned object
  • useImperativeHandle uses a simple summary:
    • Function: Reduce the DOM element properties exposed to the parent component, and only expose the DOM methods that the parent component needs to use
    • Parameter 1: The ref attribute passed by the parent component
    • Parameter 2: Return an object to be used in the parent component to call the method in the object through ref.current

Example:

parent component:

import React, { useState, useEffect, useRef } from 'react';
 
 
const cRef = useRef() as React.MutableRefObject<any>;
 
 
//使用子组件暴露出来的方法   cRef.current
 
const handleAgree = async () => {
const res = await cRef.current.onFinish();
}
 
 
<Modal
   title="云端情报库"
   visible={isShow}
   onOk={handleAgree}
   onCancel={handleOff}
   destroyOnClose={true}
>
//CloudIntelligence 子组件
    <CloudIntelligence
       cRef={cRef}
       data={dataform}
     />
</Modal>

 Subassembly:

import React, { useState, useImperativeHandle, useEffect } from 'react';
 
 
//子组件解析出来
const { cRef, data } = props;
 
 
// 将方法暴露给父组件使用
useImperativeHandle(cRef, () => ({
   form,
   onFinish,
}));

Review the combination of ref and forwardRef:

  • ref can be forwarded to subcomponents through forwardRef
  • The child component gets the ref created by the parent component and binds it to one of its own elements
import React, { useRef, forwardRef } from 'react'
 
// forwardRef可以将ref转发给子组件
const JMInput = forwardRef((props, ref) => {
  return <input type="text" ref={ref} />
})
 
export default function ForwardDemo() {
  // forward用于获取函数式组件DOM元素
  const inputRef = useRef()
  const getFocus = () => {
    inputRef.current.focus()
  }
 
  return (
    <div>
      <button onClick={getFocus}>聚焦</button>
      <JMInput ref={inputRef} />
    </div>
  )
}

There is nothing wrong with the forwardRef approach itself, but we directly expose the DOM of the child component to the parent component:

  • The problem with direct exposure to parent components is that some situations are uncontrollable
  • The parent component can perform arbitrary operations after getting the DOM
  • We just want the focus that the parent component can operate, and we don't want it to operate other methods at will

React hooks subcomponents pass parameters to parent components (useContext) 

import React, { useState, useContext  } from 'react';
import { ChildrenContext } from '../index';
import { Button } from 'antd';
export const Children= (props) => {
    const { setParent } = props;
    const baseval = useContext(ChildrenContext);
    const onClick= () => {
        setParent(false);
    }
    return (
        <Button type="primary" onClick={()=>onClick()}>点击</Button>
    );
}

parent component:

import React, { useState, createContext } from 'react';
import {Children} from './Children.js';
export const ChildrenContext = createContext();
export const Parent = () => {
    const [parent, setChildren] = useState(false);
    return (
         <ChildrenContext.Provider value={parent}>
            <Children setParent={setChildren}/>
         </ChildrenContext.Provider>
    );
}

Guess you like

Origin blog.csdn.net/Z_Gleng/article/details/127310935