28

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
  • 17,954
  • 13
  • 49
  • 82
  • 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

2 Answers2

35

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
  • 17,954
  • 13
  • 49
  • 82
2

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
  • 708
  • 7
  • 9