Skip to content

ref={callback} or ref ={string} ? #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
yuxino opened this issue Feb 12, 2018 · 2 comments
Closed

ref={callback} or ref ={string} ? #43

yuxino opened this issue Feb 12, 2018 · 2 comments

Comments

@yuxino
Copy link
Owner

yuxino commented Feb 12, 2018

Before using React . I was a Vue developer.

We know in Vue, ref is a special attributes. ref used to register a reference to an element or a child component. The reference will be registered under the parent component’s $refs object. If used on a plain DOM element, the reference will be that element; if used on a child component, the reference will be component instance.

Let's give an example 🌰 if we want to get context2d instance of this canvas , we should get the canvas element itselft first . So we add a ref attributes.

<canvas ref="canvas" />

And then we got that in mounted function .

mounted () {
  const 2d = this.$refs.canvas.getContext('2d');
}

For the first time I used react . I guess React also can do that . So i pass a string to ref , then i got plain object successfully . I thought everything was so for granted . But i am wrong.

I realized this is a mistake when one day i was looking at the source code of a component.

image

I found that it componet author did not use string and it was using callback function . Why he used callback instead of string . Provoked my curiosity.

I started looking for reasons at Google , Soon I found a react issues.

We can see gaearon say ref="string" is a flawed pattern. 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.
  • 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.
  • 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.

And someone ask him ....

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.
@gaearon Could you please elaborate more, what's the ref declaration and use in your example?

That is example

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} />
  }
}

So we use callback as much as possible instead of string . Because maybe one of the string will be discarded.We can see more in official document

@gaearon
Copy link

gaearon commented Feb 12, 2018

We're going to add a new object ref API in the next release.
It is going to replace string refs. Calback refs will stay for more advanced use cases.

https://github.com/reactjs/rfcs/blob/master/text/0017-new-create-ref.md

class MyComponent extends Component {
  canvas = React.createRef();

  componentDidMount() {
    const 2d = this.canvas.getContext('2d');
  }

  render() {
    return <canvas ref={canvas} />
  }
}

@yuxino
Copy link
Owner Author

yuxino commented Feb 12, 2018

@gaearon Sorry to bother you, I just copied a reference to my note. Did't realize you will reply me !! Thank you for your reply. Let me know the new object ref API of next release.

React is a great framework and you are awesome !! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants