Skip to content
This repository has been archived by the owner on Aug 19, 2022. It is now read-only.

Radium incompatible with React ref forwarding #1010

Closed
mmarcuccio opened this issue Oct 20, 2018 · 5 comments
Closed

Radium incompatible with React ref forwarding #1010

mmarcuccio opened this issue Oct 20, 2018 · 5 comments

Comments

@mmarcuccio
Copy link

mmarcuccio commented Oct 20, 2018

Any component which uses React ref forwarding fails to render when wrapped in the Radium higher order component.

I have created a minimal reproduction of this issue.

Relevant code from repro:

// This works
const TestRadium = Radium(props => <div>Radium works</div>);

// This works
const TestForwardRefs = React.forwardRef((props, ref) => (
  <div ref={ref}>Forward refs work</div>
));

// This does not render
const TestBoth = Radium(TestForwardRefs);
@mmarcuccio
Copy link
Author

mmarcuccio commented Oct 20, 2018

I have added unit tests for this issue. Only the last test fails: 'forwarded refs can be rendered when they are wrapped by a Radium HOC'

@kylecesmat
Copy link
Contributor

Thank you so much for providing a reproduction w/ a unit test! Makes traversing the issue much easier. I'll pull it down and investigate.

@kylecesmat kylecesmat added bug verified investigate Need to look at and removed investigate Need to look at labels Oct 24, 2018
@mmarcuccio
Copy link
Author

mmarcuccio commented Nov 7, 2018

It looks like react-redux also had an issue with forward refs with their connect HoC. I'm not sure if this issue is similar, but if it is then it could potentially be useful to learn from their solution.

@blainekasten
Copy link
Contributor

@mmarcuccio I spent a lot of time trying to find ways to make this work. Unfortunately, do to the way Radium works, I currently believe we will never be able to support this flow. A good note is we can always support the ref being forwarded onto the Radium component like this:

const Comp = Radium(class extends Component {
  render() {
    return <div id={1} ref={this.props.forwardedRef} />;
  }
}

const Wrapped = React.forwardRef((props, ref) => (
  <Comp {...props} forwardedRef={ref} />
));

The reason we can't support Radium wrapping a forwardedRef is because Radium highjacks the render cycle, scans the children, and applies styles as necessary. The forwardRef returns a special React implementation of an object like this:

{
  $$typeof: Symbol('react.ref'),
  render: function()
}

It's not a typical class, or function, and makes it seemingly impossible to get the contents of it's grandchildren. So at this time, I believe the suggested way for Radium is to just use the above flow. If you have any other ideas, thoughts or questions let me know. But at this time I'm going to close this ticket as can't do.

@mmarcuccio
Copy link
Author

@blainekasten that makes sense, thank you for investigating!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants