函数组件 useRef -组件设计
React 组件的 ref 可以帮助我们拿到组件的实例或者 DOM 对象,从而对组件内部进行修改。日常开发中,为了使得组件具有通用性,就需要减少组件之间的依赖关系。合理地使用 ref ,使得子组件只需暴露出 ref 实例方法 ,父组件无需关注子组件内部调用子组件的实例方法。
涉及到 React 相关的 API
- [useRef](Hook API 索引 – React (docschina.org))
- [forwardRef](React 顶层 API – React (reactjs.org))
- useImperativeHandle
- connect
场景:一个页面有个按钮,希望点击后出现一个弹窗,所以这个页面和弹窗组成父子组件的关系。(弹窗内部数据是由 redux 管理)
需求:弹窗组件 visible 属性交给自己管理,希望通过 useRef 暴露出一个 open() 方法,给父组件去使用,无需关注组件实现细节
子组件:弹窗组件
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 36 37 38 39 40 41 42 43 44 45 46 47 48
|
import React, { useState, forwardRef, useImperativeHandle } from 'react' import { Form, Modal } from 'antd' import { connect } from 'react-redux'
function Child({ refInstance }) { const [visible, setVisible] = useState(false)
useImperativeHandle( refInstance, () => ({ open: () => { setVisible(true) }, }), [] )
return ( <Modal title="表单预览" visible={visible} footer={null} onCancel={() => setVisible(false)} > { // 展示 redux 数据 redux_data } </Modal> ) }
const ChildrRefWrap = connect((state) => ({ redux_data: state.redux_data, }))(Render)
export default forwardRef((props, ref) => ( <RenderRefWrap {...props} refInstance={ref} /> ))
|
父组件:Father
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import React, {useRef} from 'react' import { Button } from "antd"
export default function Father() { onst modalRef = useRef(null)
const onPreviewClick = ()=> { modalRef.current.open() } return ( <div> <Button type="primary" size="small" onClick={onPreviewClick}>预览效果</Button> </div> ) }
|
参考:React 函数式组件使用 Ref - 掘金 (juejin.cn)