React Native中ref的用法(通過組件的ref屬性,來獲取真實的組件)


ref是什么?
ref是組件的特殊屬性,組件被渲染后,指向組件的一個引用。可以通過組件的ref屬性,來獲取真實的組件。因為,組件並不是真正的DOM節點,而是存在於內存中的一種數據結構,
稱為虛擬的DOM,只有當它真正的插入文檔之后,才變為真正的DOM節點。根據React的設計,所以的DOM變動都發生在虛擬DOM上,然后再將實際的部分反映到真實的DOM上--這就是 DOM DIff,它可以提高頁面性能。 如何使用ref呢? ref屬性的定義是在使用組件的部分,而組件的方法之類的都是在定義組件的里面就有的。render方法被調用的時候,組件就會被渲染。渲染完成之后,就可以獲取這個組件實例啦,因而就可以調用組件實例里的方法或者變量啦。

React的ref有3種用法:

1. 字符串(已廢棄)
2. 回調函數
3. React.createRef() (React16.3提供)

1. 字符串

最早的ref用法。

1.dom節點上使用,通過this.refs[refName]來引用真實的dom節點

1 <input ref="inputRef" /> //this.refs['inputRef']來訪問

2.類組件上使用,通過this.refs[refName]來引用組件的實例

<CustomInput ref="comRef" /> //this.refs['comRef']來訪問

 

2. 回調函數

回調函數就是在dom節點或組件上掛載函數,函數的入參是dom節點或組件實例,達到的效果與字符串形式是一樣的,
都是獲取其引用。

回調函數的觸發時機:。

1. 組件渲染后,即componentDidMount后
2. 組件卸載后,即componentWillMount后,此時,入參為null
3. ref改變后

1.dom節點上使用回調函數

1 <input ref={(input) => {this.textInput = input;}} type="text" />

2.類組件上使用使用回調函數

1 <CustomInput ref={(input) => {this.textInput = input;}} />

3.可用通過props跨級傳遞的方式來獲取子孫級dom節點或組件實例

下面是在跨兩級獲取到孫級別的組件內部的dom節點

 1 function CustomTextInput(props) {
 2     return (
 3         <div>
 4             <input ref={props.inputRef} />
 5         </div>
 6     );
 7 }
 8 function Parent(props) {
 9   return (
10     <div>
11       My input: <CustomTextInput inputRef={props.inputRef} />
12     </div>
13   );
14 }
15 class Grandparent extends React.Component {
16   render() {
17     return (
18       <Parent
19         inputRef={el => this.inputElement = el}
20       \/>
21     );
22   }
23 }

3.React.createRef()

在React 16.3版本后,使用此方法來創建ref。將其賦值給一個變量,通過ref掛載在dom節點或組件上,該ref的current屬性
將能拿到dom節點或組件的實例
例如

 1 class Child extends React.Component{
 2     constructor(props){
 3         super(props);
 4         this.myRef=React.createRef();
 5     }
 6     componentDidMount(){
 7         console.log(this.myRef.current);
 8     }
 9     render(){
10         return <input ref={this.myRef}/>
11     }
12 }

4.React.forwardRef

同樣是React 16.3版本后提供的,可以用來創建子組件,以傳遞ref。
例如:

 1 //子組件(通過forwardRef方法創建)
 2 const Child=React.forwardRef((props,ref)=>(
 3   <input ref={ref} />
 4 ));
 5 
 6 //父組件
 7 class Father extends React.Component{
 8   constructor(props){
 9     super(props);
10     this.myRef=React.createRef();
11   }
12   componentDidMount(){
13     console.log(this.myRef.current);
14   }
15   render(){
16     return <Child ref={this.myRef}/>
17   }
18 }

子組件通過React.forwardRef來創建,可以將ref傳遞到內部的節點或組件,進而實現跨層級的引用。

forwardRef在高階組件中可以獲取到原始組件的實例

例如:

 1 //生成高階組件
 2 const logProps=logProps(Child);
 3 
 4 //調用高階組件
 5 class Father extends React.Component{
 6   constructor(props){
 7     super(props);
 8     this.myRef=React.createRef();
 9   }
10   componentDidMount(){
11     console.log(this.myRef.current);
12   }
13   render(){
14     return <LogProps ref={this.myRef}/>
15   }
16 }
17 
18 //HOC
19 function logProps(Component) {
20   class LogProps extends React.Component {
21     componentDidUpdate(prevProps) {
22       console.log('old props:', prevProps);
23       console.log('new props:', this.props);
24     }
25 
26     render() {
27       const {forwardedRef, ...rest} = this.props;
28 
29       // Assign the custom prop "forwardedRef" as a ref
30       return <Component ref={forwardedRef} {...rest} />;
31     }
32   }
33 
34   // Note the second param "ref" provided by React.forwardRef.
35   // We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
36   // And it can then be attached to the Component.
37   return React.forwardRef((props, ref) => {
38     return <LogProps {...props} forwardedRef={ref} />;
39   });
40 }
 1 //生成高階組件
 2 const logProps=logProps(Child);
 3 
 4 //調用高階組件
 5 class Father extends React.Component{
 6   constructor(props){
 7     super(props);
 8     this.myRef=React.createRef();
 9   }
10   componentDidMount(){
11     console.log(this.myRef.current);
12   }
13   render(){
14     return <LogProps ref={this.myRef}/>
15   }
16 }
17 
18 //HOC
19 function logProps(Component) {
20   class LogProps extends React.Component {
21     componentDidUpdate(prevProps) {
22       console.log('old props:', prevProps);
23       console.log('new props:', this.props);
24     }
25 
26     render() {
27       const {forwardedRef, ...rest} = this.props;
28 
29       // Assign the custom prop "forwardedRef" as a ref
30       return <Component ref={forwardedRef} {...rest} />;
31     }
32   }
33 
34   // Note the second param "ref" provided by React.forwardRef.
35   // We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
36   // And it can then be attached to the Component.
37   return React.forwardRef((props, ref) => {
38     return <LogProps {...props} forwardedRef={ref} />;
39   });
40 }

注意:
1. ref在函數式組件上不可使用,函數式組件無實例,但是其內部的dom節點和類組件可以使用
2. 可以通過ReactDOM.findDOMNode(),入參是一個組件或dom節點,返回值的組件對應的dom根節點或dom節點本身
   通過refs獲取到組件實例后,可以通過此方法來獲取其對應的dom節點
3. React的render函數返回的是vDom(虛擬dom)

 

參考:https://blog.csdn.net/liangklfang/article/details/72858295
         https://blog.csdn.net/liwusen/article/details/80009968


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM