Get ref for Glamorous Component
Accessing a glamorous component's ref
is a bit different.
Normal ref Access
In React, the ref
is an attribute on a component that allows you to access the actual DOM element that the component is bound to. This is important for anything that requires direct DOM access, such as focus control.
The ref
prop takes a callback function whose parameter is the DOM element. So to save a reference to the DOM element, one might write:
class MyComponent extends React.Component {
componentDidMount() {
console.log(this.el)
}
render() {
return <div ref={el => (this.el = el)}>some ui</div>
}
}
// outputs <div /> DOM node
Glamorous Difference
Glamorous is different, however. If you create a Glamorous component and then put a ref
prop on it, you get something different:
import glamorous from 'glamorous'
const SomeUi = glamorous.div({ some: 'styles' })
class MyComponent extends React.Component {
componentDidMount() {
console.log(this.el)
}
render() {
return <SomeUi ref={el => (this.el = el)}>some ui</SomeUi>
}
}
// outputs ThemedComponent (glamorous) backing instance
This is somewhat unexpected. Instead, glamorous gives you a new prop to use: innerRef
.
Adjusting the example above, we can make this all better by using innerRef
:
return <SomeUi innerRef={el => (this.el = el)}>some ui</SomeUi>
Wrapping the New API
From the outside, however, I don't want clients of my component to care if I use glamorous internally for styling or not. I also want them to be able to send in ref
normally if they need to access the DOM element.
To accomplish this we always wrap a glamorous component with another non-glamorous React component so we can make the translation:
import glamorous from 'glamorous'
const SomeUi = glamorous.div({ some: 'styles' })
class MyComponent extends React.Component {
componentDidMount() {
console.log(this.el)
}
render() {
return <SomeUi innerRef={this.props.ref}>some ui</SomeUi>
}
}
So that when I use this component, I can use ref
as I'd normally expect:
<MyComponent ref={el => (this.childEl = el)} />
What do you think? Is this a good idea? How would you make ref
usage predictable in this case?