Using 'ref' on React Styled Components is not working
Asked Answered
R

3

30

I am having difficulty using refs with Styled Components. When I try to access them in my class methods like below, I get the following error:

Edit.js:42 Uncaught TypeError: this.....contains is not a function

  constructor(props) {
    ....
    this.setWrapperRef = this.setWrapperRef.bind(this);
    this.handleClickOutside = this.handleClickOutside.bind(this);
   }
----------
  setWrapperRef = (node) => {
    this.wrapperRef = node;
  }
  handleEdit = (e) => {
    e.preventDefault();
    this.props.onEdit(this.props.id, this.state.title);
  }
----------
<Wrapper onSubmit={this.handleEdit} ref={this.setWrapperRef}>
  ...
</Wrapper>

I found the code from this question

What am I doing wrong here?

Rowan answered 12/6, 2018 at 15:22 Comment(1)
★ As of styled-components v4 using the ref prop works fine → Docs linkBedlamite
R
38

I found the answer myself. The solution is to use innerRef instead of ref as the ref itself points to the Styled Component and not the DOM node.

A detailed discussion can be found on GitHub

Rowan answered 12/6, 2018 at 15:24 Comment(6)
This is also in the docs.Incurrence
For v4 and above, use the ref prop directly instead.Yokefellow
I got a warning from Emotion that the innerRef is going to be deprecated in the futureLowelllowenstein
does it work in react native ? answer: noCavalla
@DimitriKopriwa did you find a solution on how to type ref on react-native?Modest
Either don't uise styled, or use useRef, but with createRef, forget about it, you can thumbs up here to say you have the same problem : github.com/styled-components/styled-components/issues/3823Cavalla
S
3

If you extend another component in styled ref forwarding requires efford. so my solution was extending that component with as prop.

before:

import { useRef } from 'react'
import styled from 'styled-components'

const Card = styled.div``
const Block = styled(Card)``

const Component = () => {
    const ref = useRef(null);
    return <Card ref={ref} />
}

after:

import { useRef } from 'react'
import styled from 'styled-components'

const Card = styled.div``
const Block = styled.div``

const Component = () => {
    const ref = useRef(null);
    return <Block as={Card} ref={ref} />
}
Serotonin answered 18/6, 2020 at 12:45 Comment(0)
G
0

    const StyledComponent = styled.div.attrs(({ref}) => ({
      ref: ref,
    }))``

    const App = () => {
      const anyRef = useRef();

      return <StyledComponent ref={anyRef}/>
    };
Gnat answered 19/7, 2022 at 20:44 Comment(1)
Please read How do I write a good answer?. While this code block may answer the OP's question, this answer would be much more useful if you explain how this code is different from the code in the question, what you've changed, why you've changed it and why that solves the problem without introducing others. - From ReviewScuff

© 2022 - 2025 — McMap. All rights reserved.