当前位置:   article > 正文

【react+ts- forwardRef】_forwardref ts

forwardref ts


引用传递(Ref forwading)是一种通过组件向子组件自动传递 引用ref 的技术。对于应用者的大多数组件来说没什么作用。但是对于有些重复使用的组件,可能有用。例如某些input组件,需要控制其focus,本来是可以使用ref来控制,但是因为该input已被包裹在组件中,这时就需要使用Ref forward来透过组件获得该input的引用。

作者:pipu
链接:https://www.jianshu.com/p/fac884647720/
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

1. 学习资料

JS-react forward ref高阶组件透传-1
JS-react forward ref高阶组件透传-2
TS-react forward ref高阶组件透传

2. 普通input透传

2.1 TS版本

Parent.tsx

import React, { useRef, useState } from 'react'
import Child from './Child';

export default function Parent() {
  const inputRef = useRef<HTMLInputElement>(null);
  const [text,setText] = useState<string>('');
  return (
    <div>
      <button onClick={()=>{
        inputRef.current?.focus();
        setText('');
      }}>父组件内按钮-点击input获取焦点并清空value</button>
      <Child ref={inputRef} text={text} changeVal={(val:string)=>{
        setText(val);
      }}></Child>
    </div>
  )
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Child.tsx

import React, { ChangeEvent, forwardRef, MutableRefObject, useCallback, useRef } from 'react'

interface Iprops {
  text:string;
  changeVal:Function
}

const Child = forwardRef<HTMLInputElement,Iprops>((props,ref) => {
const localRef = useRef<HTMLInputElement | null>(null);

const onChange = useCallback((e:ChangeEvent<HTMLInputElement>)=>{
  props.changeVal(e.target.value)
},[props]);

return (
  <div>
    <input type="text" value={props.text} ref={el=>{
      localRef.current = el;
      console.log(ref)
      if (typeof ref === 'function') {
        ref(el);
      } else if (ref) {
        (ref as MutableRefObject<HTMLInputElement>).current = el!;
      }
    }} onChange={onChange}/>
    <button onClick={()=>{
      console.log(localRef.current)
      console.log(localRef.current?.value)
      console.log(props.text)
    }}>子组件内按钮-点击获取input输入值</button>
  </div>
)
}) 

export default Child
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

2.2 JS版本

Child.tsx

import React, { forwardRef, useCallback} from 'react'
const Child = forwardRef((props,ref) => {
	const onChange = useCallback((e)=>{
	  props.changeVal(e.target.value)
	},[props]);

	return (
	  <div>
	    <input type="text" value={props.text} ref={ref} onChange={onChange}/>
	    <button onClick={()=>{
	      console.log(ref.current)
	      console.log(ref.current.value)
	      console.log(props.text)
	    }}>子组件内按钮-点击获取input输入值</button>
	  </div>
	)
}) 

export default Child
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

3. TS-Antd-Form组价透传

Parent.tsx

import React, { useRef } from 'react'
import type { FormInstance } from 'antd/es/form';
import Child from './Child';

export default function Parent() {
  const addForm = useRef<FormInstance>(null);
  const updateForm= useRef<FormInstance>(null);
  return (
    <div>
      <button onClick={()=>{
        addForm.current?.validateFields()
        	.then((values) => {
        		console.log(values);
        	})
        	.catch((err) => {
		        console.log(err);
		     });
        
      }}>父组件内按钮-点击input获取焦点并清空value</button>
      <UserForm ref={addForm} regionList={regionList} roleList={roleList} />
      <UserForm ref={updateForm} regionList={regionList} roleList={roleList} />
    </div>
  )
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

Child.tsx

import React, { forwardRef, MutableRefObject, Ref, useEffect} from "react";
import { Form } from "antd";
import type { FormInstance } from 'antd/es/form';

interface UserFormProps {
  isUpdateRegionDisabled?:boolean;
  regionList:any[];
  roleList:any[];
}
const assignRefs = <T extends unknown>(...refs: Ref<T | null>[]) => {
  return (node: T | null) => {
    refs.forEach((r) => {
      if (typeof r === "function") {
        r(node);
      } else if (r) {
        (r as MutableRefObject<T | null>).current = node;
      }
    });
  };
};

const UserForm = forwardRef<FormInstance,UserFormProps>((props,ref)=>{
	const localRef = React.useRef<FormInstance | null>(null);
	useEffect(() => {
    	console.log('localRef',localRef.current)
  	}, [props]);
	return (
		<Form layout="vertical" ref={assignRefs(localRef, ref)}></Form>
	)
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/65979
推荐阅读
相关标签
  

闽ICP备14008679号