Skip to content

09.类组件的ref源码实现

具体代码演化过程请观看视频,这里呈现关键代码:

js
// react.js
function createRef() { 
    return { current: null };
}
const React = {
    createElement,
    Component,
    createRef 
}
js
// react-dom.js
export function createDOM(VNode){
    if(!VNode) return
    const {type, props, ref} = VNode 
    // 此处省略原有代码若干...
    VNode.dom = dom
    ref && (ref.current = dom) 
    return dom
}


function getDomByClassComponent(vNode){
    let { type, props, ref } = vNode;
    let instance = new type(props)
    ref && (ref.current = instance); 
    let renderVNode = instance.render();
    instance.oldVNode = renderVNode
    if (!renderVNode) return null;
    return createDOM(renderVNode);
}
js
//index.js
class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    // create a ref to store the textInput DOM element
    this.textInput = React.createRef();
    this.focusTextInput = this.focusTextInput.bind(this);
  }

  focusTextInput() {
    // Explicitly focus the text input using the raw DOM API
    // Note: we're accessing "current" to get the DOM node
    this.textInput.current.focus();
  }

  render() {
    // tell React that we want to associate the <input> ref
    // with the `textInput` that we created in the constructor
    return (
      <div>
        <input
          type="text"
          ref={this.textInput} />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}

class AutoFocusTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();
  }

  componentDidMount() {
    this.textInput.current.focusTextInput();
  }

  render() {
    return (
      <CustomTextInput ref={this.textInput} />
    );
  }
}

基于 VitePress 构建