如果又忘了为什么ref即将废弃string name就来看这篇文章

581 阅读2分钟

ref调用的三种方式

  1. stringName (即将被废弃)
  2. createRef()
  3. 回调函数 ref={ref => this.refName = ref ;}

ref 为什么要废弃 stringName的方式

根据官方给的回答是这样的:reactjs.org/docs/refs-a…

If you worked with React before, you might be familiar with an older API where the ref attribute is a string, like "textInput", and the DOM node is accessed as this.refs.textInput. We advise against it because string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases.

而这里的issues说的是什么呢?github.com/facebook/re…

There are multiple problems with it:

  • It requires that React keeps track of currently rendering component (since it can't guess this). This makes React a bit slower.由于它无法知道this,所以需要React去跟踪当前渲染的组件。这使得React变得比较慢(当 ref 定义为string 时,需要 React 追踪当前正在渲染的组件,在 reconciliation 阶段, React Element 创建和更新的过程中, ref 会被包装为一个闭包函数, 等待 commit 阶段被执行,这会对React 的性能产生一些影响.)

  • It doesn't work as most people would expect with the "render callback" pattern (e.g. ) because the ref would get placed on DataGrid for the above reason. string类型的refs写法会让ref被放置在DataTable组件中,而不是MyComponent中

class MyComponent extends Component {
  renderRow = (index) => {
    // This won't work. Ref will get attached to DataTable rather than MyComponent:
    return <input ref={'input-' + index} />;

    // This would work though! Callback refs are awesome.
    return <input ref={input => this['input-' + index] = input} />;
  }
 
  render() {
    return <DataTable data={this.props.data} renderRow={this.renderRow} />
  }
}
  • It is not composable, i.e. if a library puts a ref on the passed child, the user can't put another ref on it (e.g. #8734). Callback refs are perfectly composable. 如果某个库的组件,在子组件放了个string类型的ref,那么用这个组件的人就没法在放个ref在上面,进而取到子组件的实例

关于第三点来说,有个例子,

function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />
    </div>
  );
}

class Parent extends React.Component {
  render() {
    return (
      <CustomTextInput
        inputRef={el => this.inputElement = el}
      />
    );
  }
}

父组件都可以通过这种写法,直接通过this.inputElement拿到子组件中的具体Dom元素。而传统的字符串形式的ref,相对于这种语法,就可以看出不是足够灵活了。