29

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?

nikjohn
  • 20,026
  • 14
  • 50
  • 86
  • 3
    ★ As of *styled-components* `v4` using the `ref` prop works fine → [Docs link](https://www.styled-components.com/docs/advanced#refs) – vsync Oct 27 '19 at 11:04

3 Answers3

37

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

nikjohn
  • 20,026
  • 14
  • 50
  • 86
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} />
}
mkg
  • 769
  • 7
  • 9
-1

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

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

      return <StyledComponent ref={anyRef}/>
    };
SID JO
  • 1
  • 1
  • 1
    Please read [How do I write a good answer?](https://stackoverflow.com/help/how-to-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 Review](https://stackoverflow.com/review/low-quality-posts/32238228) – Saeed Zhiany Jul 20 '22 at 05:07