React中使用TS完成父组件调用子组件的操作方法

来自:网络
时间:2023-07-25
阅读:
目录

1.需求

由于在项目开发过程中,我们往往时需要调用子组件中的方法。例如管理系统中的添加,就需要我们调用添加表单时展示的方法。从而实现页面的展示。在vue中我们知道可以给组件上添加ref从而获取到组件的实例对象。那么在React中我们该怎么办呢、

2.页面

2.1父组件

下面就是我们的父组件,其实就是类似于一个网站的头部,当我们点击用户登录时,就需要将我们写登录逻辑的页面展示出来。因此我们就需要调用对应的Ref从而帮助我们操作对应的子组件的方法。

const WebHeader = () => {
const ModelRef = useRef<IFnChildInstance>(null)
const ChildrenFn = ModelRef.current!
function userLogin(){
ChildrenFn.showModal()
console.log(ChildrenFn.showModal)
}
return (
<div className="header-container fx fa">
<div className="wrapper fx jb fa">
<div className="left-wrapper fx fa">
<img src="http://syt.atguigu.cn/_nuxt/img/logo.7086376.png" alt="网站loge" style={{width:'50px'}}/>
<span className='text link'>尚医通 预约挂号统一平台</span>
</div>
<div className="right-wrapper fx jb">
<span className='link-to'>帮助中心</span>
<span className='link-to' onClick={userLogin}>登录注册</span>
<Child ref={ModelRef}></Child>
</div>
</div>
</div>
)
}

2.2 子组件

这里的子组件就超级简单了,我们就只是在这里定义了一个弹窗从而实现登录的逻辑。这里就只是简单的将子组件中的弹出的方法暴露给父组件,从而让父组件点击登录的时候可以展开我们对应的子组件。

const Child = forwardRef<IFnChildInstance>((props,ref) => {
const [isModalOpen, setIsModalOpen] = useState(false);
useImperativeHandle(ref, () => ({
showModal, //(实际等于: resetSharePopup:resetSharePopup)
}));
function showModal(){
setIsModalOpen(true);
};
return(
<Modal title="Basic Modal" open={isModalOpen}>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
)
})

3.实现逻辑

3.1 父组件中构建ref

由于我们需要获取到对应的子组件的ref,因此我们首先需要在父组件中获取到对应的。由于我们这里定义的是函数式组件,因此在这里我们就使用了对应的hooks,如useRef。因为这里我们使用了TS,因此我们对创建的Ref进行了类型的限制。

const ModelRef = useRef<IFnChildInstance>(null)

因为在这里我们主要是获取子组件中打开弹窗的方法,因此我们采取的是只是暴露方法,而不需要将DOM元素暴露出来。因此其中的IFnChildInstance就是我们定义的接口类型。其中的showModal的类型是一个无返回值的函数。然后我们将定义好的ref放在对应的组件,到这里我们的父组件中所实现的相关操作已经完成了。

interface IFnChildInstance {
        showModal: () => void,
}
//组件引用的地方
<Child ref={ModelRef}></Child>

3.2子组件中的相关操作

首先我们需要使用的是forwardRef来进行向外暴露。下面是官方文档中对其的介绍。

forwardRef 允许你的组件使用 ref 将一个 DOM 节点暴露给父组件。

forwardRef(render)

使用 forwardRef() 来让你的组件接收一个 ref 并将其传递给一个子组件:

import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
// ...
});
  • props:父组件传递过来的参数。
  • ref:父组件传递的 ref 属性。ref 可以是一个对象或函数。如果父组件没有传递一个 ref,那么它将会是 null。你应该将接收到的 ref 转发给另一个组件,或者将其传递给 useImperativeHandle
  • 对应的官方文档的链接如下,需要的可以跳转过去仔细查看forwardRef – React

回归正题,我们这里就使用forwardRef来进行对应的创建。代码如下。由于我们在父组件中传递的ref所对应的类型是IFnChildInstance,因此我们在这里接收的时候也要进行变量类型的生命。然后由于我们子组件只需要将其对应的方法暴露给父组件中操作,而不是将整个DOM元素给父组件,因此我们可以使用useImperativeHandle来进行操作。其中对应的具体使用方法可以点击上面的连接进行查看。这里就只是简单阐述了,第一个参数接收的是函数传递的ref,第二个使我们想向外暴露的方法。该参数的类型是一个函数,因此这里我们就使用了赋值的心事。第三个参数是一个数组,具体的使用方法还请查看官方文档。然后我们还需要在子组件中定义所传递给父组件中的方法。注意的是其函数的类型要和我们所定义的ref的类型一样,否则TS会给我们报错提示。

const Child = forwardRef<IFnChildInstance>((props,ref) => {
const [isModalOpen, setIsModalOpen] = useState(false);
useImperativeHandle(ref, () => ({
showModal, //(实际等于: resetSharePopup:resetSharePopup)
}));
function showModal(){
setIsModalOpen(true);
};
return(
<Modal title="Basic Modal" open={isModalOpen}>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
)
})

4.父组件使用

然后我们就可以通过父组件中定义的接口useRef的变量中的.current属性来获取我们子组件中传递返回的对象,其中就是我们所定义返回的函数。然后我们就只需要在合适的地方将其调用即可。

const ModelRef = useRef<IFnChildInstance>(null)
  const ChildrenFn = ModelRef.current!
  function userLogin(){
    ChildrenFn.showModal()
   console.log(ChildrenFn.showModal)

5.总结

首先我们需要使用useRef来创建对应的ref的值,但是我们需要给对应的值定义接口。其中接口的信息就是我们想往外暴露的值

然后再对应的组件上使用ref来进行获取对应的标签

然后在子组件中我们需要使用forwardRef向外暴露一个可操作的ref。其中的值为props和ref,分别与之对父组件传递值时的接口

useImperativeHandle(ref,()=>{({})},[])的形式只是暴露我们所需要的方法或者参数,其他的就不用暴露给父组件,这样方便于我们操作

然后就完成了操作子组件的相关方法。

该总结只是作为我刚使用TS完成父子组件调用值。可能会有啥总结的不正确或者文章中有啥错误也可以指出讨论。共同进步

返回顶部
顶部