-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
[V2] innerRef doesn't work with styled(Component) #618
Comments
I've just notice this bug was also present in |
This is not a bug, but due to how the "innerRef" logic works. Once it's in the input props, it will pass it innerRef as ref to the underlying element , I.e. The unstyled component in your example. Thus the component that renders Input will receive a ref, but it won't be the element, but the unstyled component itself. If you want the element ref then either add your own ref prop and set it on the component instance, so that you can access it with its ref, or use findDOMNode. |
@philpl can you please elaborate I didn't really get it. I have read here the recommendation.
Could you please show a small example in the best case update the webpackbin to see how you would handle the problem ?
There is a warning if you use findDOMNode. You are not supposed to use findDOMNode as they won't work (haven't tried) in react-native. Styled-components is targeting full compatibility with react-native so it can't be the best solution for our components. Is there any way to pass the innerRef through in case it's a styled components ? There is no reason to use innerRef if you target the styled components. I suggest to reopen this. Or the doc must be updated at some point. |
@kopax So the thing is, that we can't pass it through. We would have to expose Right now we directly pass Let's look at your example: <Input type="text" isOpen={this.state.isOpen} innerRef={(search) => { this.search = search }} />
If you want to get a DOM ref you could do: class InputUnstyled extends React.Component {
render() {
const { isOpen, ...rest } = this.props
return <input ref={input => this.ref = input} {...rest} />
}
} And then accept it like this: <Input type="text" isOpen={this.state.isOpen} innerRef={(search) => { this.search = search.ref }} /> If we'd decide to pass on input ref, then you'd have to do: class InputUnstyled extends React.Component {
render() {
const { isOpen, innerRef, ...rest } = this.props
return <input ref={innerRef} {...rest} />
}
} Which works, until you render multiple elements. At that point, you'd be up to yourself, with no way to pass anything sensible accept maybe We could also I agree that we need to add some docs for this, but I don't think that there's a better default behaviour for this use-case. |
Thanks for the detailed explanation it makes a bit more sens. This should be added to the documentation. |
@philpl Thanks .. That worked for me. In my case, I was trying to get the reference of a third party component, react-custom-scrollbar. I managed to do it in the following way
And invoked it like this
|
Couldn't we just check if the underlying component is a styled component itself, and in that scenario pass down innerRef instead of ref? |
I am trying to set the ref for a
<Input />
styled components.The component has been created with
const Input = styled(InputUnstyled)
.I have the following react app:
Version
2.0.0-8
Reproduction
https://www.webpackbin.com/bins/-Kg-9xQ8QPTOnSFLmOOt
Steps to reproduce
this.search.focus()
.It will through an error in your developer console.
Expected Behavior
The
<Input />
element should receive the:focus
.Actual Behavior
Throw error
this.search.focus is not a function
The text was updated successfully, but these errors were encountered: