React源碼閱讀—React.forwardRef

React.forwardRef

在有些時候我們想要操作子組件中的DOM節點,說到獲取DOM節點,可能我們會第一時間想到ref。可是,如果我們是直接在子組件上寫ref,獲得的只是子組件,而不是子組件下的某個DOM節點。

這個時候就可以通過React.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}/>
  }
}

源碼

export default function forwardRef<Props, ElementType: React$ElementType>(
  render: (props: Props, ref: React$Ref<ElementType>) => React$Node,
) {
  if (__DEV__) {
    if (typeof render !== 'function') {
      warningWithoutStack(
        false,
        'forwardRef requires a render function but was given %s.',
        render === null ? 'null' : typeof render,
      );
    } else {
      warningWithoutStack(
        // Do not warn for 0 arguments because it could be due to usage of the 'arguments' object
        render.length === 0 || render.length === 2,
        'forwardRef render functions accept exactly two parameters: props and ref. %s',
        render.length === 1
          ? 'Did you forget to use the ref parameter?'
          : 'Any additional parameter will be undefined.',
      );
    }

    if (render != null) {
      warningWithoutStack(
        render.defaultProps == null && render.propTypes == null,
        'forwardRef render functions do not support propTypes or defaultProps. ' +
          'Did you accidentally pass a React component?',
      );
    }
  }

  return {
    $$typeof: REACT_FORWARD_REF_TYPE,
    render,
  };
}

這個方法也僅僅是返回了一個對象而已,返回的對象裏面有一個$$typeof屬性,這並不意味着它不是一個ReactElement。在傳入ReactElement方法之後,該對象是被保存在了type屬性內,而$$typeof仍是REACT_ELEMENT_TYPE

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章