DEV Community

Cover image for Redux 101: Using `forwardRef` with Redux
James Won
James Won

Posted on

Redux 101: Using `forwardRef` with Redux

TL;DR When wrapping a component using forwardRef in Redux's connect function, make sure your connect options include enabling forwardRef

I'm not a huge redux fan. I use it if I have to and the code base requires it.

Today I ran across a really small, even stupid (on my part) problem. Why couldn't I get forwardRef to work? Here's my short story on this.

Slightly Tangential context

Until recently I was a front-end focused engineer building a design system at Xero. One of the great perks working on a design system is the use case for Redux is non-existent. So for the past 3 years I have enjoyed writing redux-less code and managing state at a component level or using the Context API where shared state was needed.

Recently, I joined a startup where Redux is used.

The problem I faced

I wanted to get a very simple solution going where I create and forward a ref down into component's internals. The use-case is quite boring - I wanted to prevent the duplication of logic by relying on the click behaviour of an existing component.

See simplified example below

// Top level
const ref = createRef()

return (
<>
  <div onClick={() => ref.current.click()}>
  <MyRefedComponent ref={ref} />
<> 
)

// MyRefedComponent
...
const MyRefedComponent = React.forwardRef((props, ref) => (
  <div onClick={boringLogic} ref={ref}> 
));
Enter fullscreen mode Exit fullscreen mode

Looks all good right? Nope, the ref always returned null.

I was first bewildered, surely I can't have forgotten how to do basic refs right? Then I started doubting the most basic parts of my code, I checked everything, and started to pull my hair out - I swapped createRef to useRef (LOL) everything except (you guessed it) checking Redux.

What was the issue?

The issue was Redux.

When you use forwardRef in a component wrapped with Redux's connect function, you need to pass in an options object with forwardRef set to true. See the Redux docs on this here.

So in my case I needed to do the following:

// MyRefedComponent
...
const MyRefedComponent = React.forwardRef((props, ref) => (
  <div onClick={boringLogic} ref={ref}> 
));

export default connect(mapStateToProps, null, null,{forwardRef: true})(MyRefedComponent)
Enter fullscreen mode Exit fullscreen mode

Lessons learned

A closer look at my code and cross-referencing to the Redux docs would have helped address this problem quickly and avoided Redux humble pie.

Though, in my defence I'm still getting accustomed to using Redux again after a very long hibernation.

I'll keep an eye out though in future for similar situations and to keep a healthy dose of scepticism around my ability using Redux.

Do you have an embarrassing story about using Redux too? Would love to learn about it please feel free to share as a comment below :)

Top comments (0)