首页 > 其他分享 >React-hooks 父组件通过ref获取子组件数据和方法

React-hooks 父组件通过ref获取子组件数据和方法

时间:2023-05-16 10:33:54浏览次数:44  
标签:setIsShow val useImperativeHandle hooks value React 组件 ref

我们知道,对于子组件或者节点,如果是class类,存在实例,可以通过 React.createRef() 挂载到节点或者组件上,然后通过 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}/>
    }
}

  

但是在子组件是函数组件的时候,因为函数组件没有实例,所以在正常情况下, ref 是不能挂载函数组件上的。那么此时,我们通过 useImperativeHandle 和 forwardRef 配合就能达到效果。

 

useImperativeHandle

useImperativeHandle:可以配合 forwardRef 自定义暴露给父组件的实例值。

useImperativeHandle为我们提供了一个类似实例的东西,它帮助我们通过useImperativeHandle 的第二个参数,将所返回的对象的内容挂载到父组件的 ref.current 上.

useImperativeHandle 接收三个参数:

① 第一个参数 ref:接收 forWardRef 传递过来的 ref。
② 第二个参数 createHandle:处理函数,返回值作为暴露给父组件的 ref 对象
③ 第三个参数 deps:依赖项 deps,依赖项更改形成新的 ref 对象。
forwardRef 会创建一个 React 组件,这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中。

下面举一个实际例子,方便大家理解:

// 子组件

const CollectAmountFormItem = forwardRef(({ isDisabled, val, handleChange }: Props, onRef: any) => {

    const [isShow, setIsShow] = useState<boolean>(val == 1); // 是否展示募集资金和剩余募集资金

	// 暴露给父组件的属性
    useImperativeHandle(onRef, () => ({
        isShow,
        setIsShow
    }));

    useEffect(() => {
        if (val == 1) setIsShow(true)
        else setIsShow(false)
    }, [val])

    /**
     * 是否募集回调
     * @param val 下拉框id
     * @param option 下拉框对象
     */
    const handleSelect = (val: any, option: any) => {
        setIsShow(val == 1);
        handleChange && handleChange(val, option);
    };

    return (
        <>
            <Col xs={20} sm={16} md={12} lg={8} xl={6}>
                <Form.Item name="isRaiseMoney" label="是否募集资金" rules={[{ required: true }]}>
                    <Select placeholder="请选择" disabled={isDisabled} onChange={handleSelect}>
                        <Select.Option value={1}>是</Select.Option>
                        <Select.Option value={0}>否</Select.Option>
                    </Select>
                </Form.Item>
            </Col>
            {
                isShow && (
                    <>
                        <Col xs={20} sm={16} md={12} lg={8} xl={6}>
                            <Form.Item name="usedMoney" label="已使用资金" rules={[{ required: isShow }]}>
                                <InputNumber
                                    formatter={value => `${value}`.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')}
                                    parser={value => `${value}`.replace(/\$\s?|(,*)/g, '')}
                                    style={{width: '100%'}}
                                    precision={2}
                                    disabled
                                    placeholder="自动计算"
                                />
                            </Form.Item>
                        </Col>
                        <Col xs={20} sm={16} md={12} lg={8} xl={6}>
                            <Form.Item name="remainMoney" label="剩余资金" rules={[{ required: isShow }]}>
                                <InputNumber
                                    formatter={value => `${value}`.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')}
                                    parser={value => `${value}`.replace(/\$\s?|(,*)/g, '')}
                                    style={{width: '100%'}}
                                    precision={2}
                                    disabled
                                    placeholder="自动计算"
                                />
                            </Form.Item>
                        </Col>
                    </>
                )
            }
        </>
  )
})

  

// 在父组件中使用

// 1、首先引入该子组件
import CollectAmountFormItem from '@/components/CollectAmountFormItem';

// 2、定义一个ref
const collectRef = useRef<any>()

// 3、使用
<CollectAmountFormItem isDisabled={isDisable} val={formData.isRaiseMoney} ref={collectRef} handleChange={handleChangeAmount} />

// 然后就可以在父组件中的一些方法中获取子组件暴露出来的方法或值,比如:

collectRef.current.setIsShow(false)

  

标签:setIsShow,val,useImperativeHandle,hooks,value,React,组件,ref
From: https://www.cnblogs.com/jiajialove/p/17404121.html

相关文章

  • Vue.js(十) element-ui PC端组件库
    一:简介饿了么公司基于Vue开发了两套UI组件库,PC端组件库和移动端组件库。一部分组件库是对原生的HTML标签元素的封装,增加了一些新的功能。另一部分组件库是原生HTML标签元素没有的,是一些比较常用的独立的功能(如:分页、进度条、加载中、树形控件等),将这些独立的常用的功能封装成......
  • react状态管理store用法二: 使用Hooks 配置redux
    react最通用的状态管理方案就是的redux,下面介绍通过Hooks的方式使用reduxnpminstallreact-redux@reduxjs/toolkit-S 创建store1.新建store文件夹,在下面新建index.tsx文件和slices文件夹,其中slices文件夹用来定义需要放进store的数据结构和方法slices文件夹下新建app......
  • react微信扫码登录
    第一步<scriptsrc="https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js">第二步//缓存已经加载的资源回调importloadScriptOncefrom'load-script-once'//加载一次functionloadScriptOnceSync(src:string,success:any){loadScriptO......
  • durandal.js 的小组件 widget
    通过在App/widgets/{your-widget-name}添加viewmodel.js和view.html文件来创建小部件为了利用Durandal的默认小部件支持,我们需要安装插件并以特定的方式组织小部件代码。首先,让我们安装插件。下面是main.js的样子define(["durandal/app"],function(app){app.c......
  • uni-app图片剪切上传;uview2用使用uview1中的图片剪切上传组件,把原有代码抽取出来
    1.其实是个组件页面,移过来就行了。2.原有组件中,可视区域和截图结果区域的长宽是一样的,所以需要调整一下;3.因为剪切图片,是在一个单独页面实现的.所以pages.json中需要加上剪切的页面路径;pages.json{ "path":"components/u-avatar-cropper/u-avatar-cropp......
  • 如何优雅的处理 React 表单
    如何优雅的处理React表单HTML表单处理本身是一件比较简单的事情,但是当我们对交互的要求高了之后,他就会变得异常复杂——尤其是在React中使用时,我们不得不创建冗长的代码去维护各种状态。那么有没有什么现成的开源方案可以供我们使用,最终优雅的创建React表单呢?本文不会详......
  • 关于Kubernetes-v1.23.6-网络组件-calico的安装部署...
    当2个workernodes节点加入到 Kubernetes/k8s集群后,我们去master节点、执行kubectlgetnodes命令就可以看到worker节点了但是我们会看到无论是master节点、还是worker节点,STATUS都会是  NotReady,如下[root@k8s-masterqq-5201351]#kubectlgetnodesNAME......
  • 小白的一次Form组件封装分享
    Form组件介绍form表单常用在回显表单信息+验证表单+提交表单信息。通常包含输入框,选择框,日期选择框,文本框等可输入的组件。封装思路通过配置文件生成一个基本的表单,然后配合数据的双向绑定得到我们提交的数据,同时尽量保留第三方UI库组件提供的属性(Attributes)、插槽(Slots)和......
  • 云原生第三周--kubernetes组件详解
    etcd组件etcd简介:etcd是CoreOS团队于2013年6月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库。etcd内部采用raft协议作为一致性算法,etcd基于Go语言实现。etcd具有下面这些属性:完全复制:集群中的每个节点都可以使用完整的存档高可用性:Etcd可用于避免......
  • 记录--9个封装Vue组件的小技巧
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助组件是前端框架的基本构建块。把它们设计得更好会使我们的应用程序更容易改变和理解。在这节课中,分享一下在过去几年中工作中学到的9个技巧。1.你可能不需要创建一个组件在创建一个组件之前,看看它是为了可重用......