目錄
- 1,介紹
- 2,類組件如何使用
- 4,應用場景-高階組件HOC
1,介紹
上篇文章中提到,ref
只能對類組件使用,不能對函數組件使用。
而 ref
轉發可以對函數組件實現類似的功能。
使用舉例:
import React, { Component } from "react";function CompA(props, ref) {return (<h1><div ref={ref}>組件A</div><span>{props.desc}</span></h1>);
}const NewCompA = React.forwardRef(CompA);export default class App extends Component {refA = React.createRef();componentDidMount() {console.log(this.refA);}render() {return <NewCompA ref={this.refA} desc="測試"></NewCompA>;}
}
打印結果
解釋:
通過 React.forwardRef()
來實現 ref
轉發。其實就是通過 HOC:參數為組件,返回新組件。
特點:
- 參數只能是函數組件,并且該函數接收2個參數:
- 參數一不變,依舊是
props
; - 參數二就是一個
ref: {current: null}
,也就是React.forwardRef()
返回的新組件接收的ref
屬性。它讓使用者來決定作為誰的引用。比如上面的例子中,就作為一個子元素的引用。
- 參數一不變,依舊是
- 返回的新組件,和原來的函數組件沒有任何區別,只是可以傳遞
ref
屬性了。
2,類組件如何使用
既然明確規定了 React.forwardRef()
的參數只能是函數,該函數的參數也是確定的,那可以將類組件包裝一層來達到目的。
更改上面的例子如下:
class CompA extends Component {render() {return (<h1><div ref={this.props.forwardRef}>組件A</div><span>{this.props.desc}</span></h1>);}
}// forwardRef 這個屬性名是隨意的,只是約定俗成為這個單詞了。
const NewCompA = React.forwardRef((props, ref) => {return <CompA {...props} forwardRef={ref}></CompA>;
});
4,應用場景-高階組件HOC
在之前的高階組件HOC中,有個問題沒有解決:
const Alog = withLog(CompA)
此時使用的是
Alog
組件,那如何獲取原組件CompA
的方法和屬性呢?
對Alog
使用ref
獲取的并不是是CompA
的組件實例。
可以使用 ref 轉發解決:
源代碼:
export default function withLog(Comp) {return class LogWrapper extends Component {componentDidMount() {console.log(`${Comp.name}組件被創建了`);}componentWillUnmount() {console.log(`${Comp.name}組件被銷毀了`);}render() {return <Comp {...this.props} />;}};
}
修改后:
import React, { Component } from "react";export default function withLog(Comp) {class LogWrapper extends Component {componentDidMount() {console.log(`${Comp.name}組件被創建了`);}componentWillUnmount() {console.log(`${Comp.name}組件被銷毀了`);}render() {const { forwardRef, ...rest } = this.props;return <Comp ref={forwardRef} {...rest} />;}}return React.forwardRef((props, ref) => {return <LogWrapper {...props} forwardRef={ref}></LogWrapper>;});
}
這樣在使用 withLog
時,并不會影響對源組件 ref
的獲取。
以上。