圖片來源於互聯網es6
React 中常規的父子組件通訊都是經過 props 進行的,子組件經過 props 來接收父組件傳遞的狀態值以及方法,從而響應視圖的更新以及事件的執行。app
在不一樣的業務場景中也會存在很是規的通訊方式,例如須要在父組件中調用子組件屬性或者方法,這個時候就須要獲取子組件的實例來解決這個問題。函數
首先須要說明的是,只有類組件纔有實例,函數式組件是沒有組件實例的。ui
React 官方提供了 3 中使用 ref 獲取實例的方式。this
class Index extends React.PureComponent {
componentDidMount() {
// 調用實例
console.log(this.refs.classComponentInstance)
}
render() {
return (
<ClassComponent ref="classComponentInstance" /> ) } } 複製代碼
class Index extends React.PureComponent {
componentDidMount() {
// 調用實例
console.log(this.classComponentInstance)
}
classComponentInstance = null
render() {
return (
<ClassComponent ref={instance => {this.classComponentInstance=instance}} /> ) } } 複製代碼
class Index extends React.PureComponent {
componentDidMount() {
// 調用實例
console.log(this.classComponentInstance.current)
}
classComponentInstance = React.createRef()
render() {
return (
<ClassComponent ref={this.classComponentInstance} /> ) } } 複製代碼
所謂的高級組件也就一個函數,以組件做爲參數,以組件做爲返回值,主要是用於處理一些類似的邏輯,使組件可高度複用。spa
// Child.js
@HocComponent
export default class Child extends React.PureComponent {
render(
return (
<div>this is Child</div>
)
)
}
// Parent.js
import Child from './Child'
class Parent extends React.PureComponent {
childComponentInstance = null
render(
return (
<Child ref={instance => {this.childComponentInstance=instance}} /> ) ) } 複製代碼
關於裝飾符可查看教程3d
上面示例中 Child 就是一個被高級組件使用裝飾符裝飾的類組件,當在 Parent 組件中調用並使用 ref 獲取其實例的時候就會發現 this.childComponentInstance 被賦值的實例並非 Child 的實例,而是 HocComponent 組件的實例。code
// Child.js
@HocComponent
export default class Child extends React.PureComponent {
componentDidMount() {
// 在 componentDidMount 週期中或者在 constructor 構造函數中執行父組件中傳遞過來的 getRef 方法,將實例 this 做爲參數
this.props.getRef(this)
}
render(
return (
<div>this is Child</div>
)
)
}
// Parent.js
import Child from './Child'
class Parent extends React.PureComponent {
childComponentInstance = null
render(
return (
<Child getRef={instance => {this.childComponentInstance=instance}} /> ) ) } 複製代碼
經過上面的方式就能夠穿透高級組件,獲取到目標組件的實例component
上面的方法雖然已經實現了咱們須要的功能,可是代碼侵入性太強,沒有複用度可言,因此咱們須要把這個功能提取出來。cdn
// util.js
export const getRef = WrapperdComponent => {
return props => {
const { getRef, ...otherProps } = props
return <WrapperdComponent ref={getRef} {...otherProps} /> } } 複製代碼
當把穿透方法提取爲一個高級組件以後就能夠在任何須要的地方調用便可
// 使用示例
// Child.js
import { getRef } from './util'
@HocComponent
@getRef
export default class Child extends React.PureComponent {
render(
return (
<div>this is Child</div>
)
)
}
// Parent.js
import Child from './Child'
class Parent extends React.PureComponent {
childComponentInstance = null
render(
return (
<Child getRef={instance => {this.childComponentInstance=instance}} /> ) ) } 複製代碼
文中若有錯誤,歡迎在評論區指正,謝謝閱讀