React ref的用法


React的ref有3種用法:

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

1. 字符串

最早的ref用法。

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

<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節點上使用回調函數

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

2.類組件上使用

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

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

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

function CustomTextInput(props) {
    return (
        <div>
            <input ref={props.inputRef} />
        </div>
    );
}
function Parent(props) {
  return (
    <div>
      My input: <CustomTextInput inputRef={props.inputRef} />
    </div>
  );
}
class Grandparent extends React.Component {
  render() {
    return (
      <Parent
        inputRef={el => this.inputElement = el}
      \/>
    );
  }
}

3.React.createRef()

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

class Child extends React.Component{
    constructor(props){
        super(props);
        this.myRef=React.createRef();
    }
    componentDidMount(){
        console.log(this.myRef.current);
    }
    render(){
        return <input ref={this.myRef}/>
    }
}

4.React.forwardRef

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

//子組件(通過forwardRef方法創建)
const Child=React.forwardRef((props,ref)=>(
  <input ref={ref} />
));

//父組件
class Father extends React.Component{
  constructor(props){
    super(props);
    this.myRef=React.createRef();
  }
  componentDidMount(){
    console.log(this.myRef.current);
  }
  render(){
    return <Child ref={this.myRef}/>
  }
}

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

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

例如:

//生成高階組件
const logProps=logProps(Child);

//調用高階組件
class Father extends React.Component{
  constructor(props){
    super(props);
    this.myRef=React.createRef();
  }
  componentDidMount(){
    console.log(this.myRef.current);
  }
  render(){
    return <LogProps ref={this.myRef}/>
  }
}

//HOC
function logProps(Component) {
  class LogProps extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('old props:', prevProps);
      console.log('new props:', this.props);
    }

    render() {
      const {forwardedRef, ...rest} = this.props;

      // Assign the custom prop "forwardedRef" as a ref
      return <Component ref={forwardedRef} {...rest} />;
    }
  }

  // Note the second param "ref" provided by React.forwardRef.
  // We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
  // And it can then be attached to the Component.
  return React.forwardRef((props, ref) => {
    return <LogProps {...props} forwardedRef={ref} />;
  });
}
//生成高階組件
const logProps=logProps(Child);

//調用高階組件
class Father extends React.Component{
  constructor(props){
    super(props);
    this.myRef=React.createRef();
  }
  componentDidMount(){
    console.log(this.myRef.current);
  }
  render(){
    return <LogProps ref={this.myRef}/>
  }
}

//HOC
function logProps(Component) {
  class LogProps extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('old props:', prevProps);
      console.log('new props:', this.props);
    }

    render() {
      const {forwardedRef, ...rest} = this.props;

      // Assign the custom prop "forwardedRef" as a ref
      return <Component ref={forwardedRef} {...rest} />;
    }
  }

  // Note the second param "ref" provided by React.forwardRef.
  // We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
  // And it can then be attached to the Component.
  return React.forwardRef((props, ref) => {
    return <LogProps {...props} forwardedRef={ref} />;
  });
}

 

注意:
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