Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to forwardRef? #39

Open
i-am-the-slime opened this issue Aug 5, 2020 · 10 comments
Open

How to forwardRef? #39

i-am-the-slime opened this issue Aug 5, 2020 · 10 comments

Comments

@i-am-the-slime
Copy link
Member

I'd like to create ReactComponents which can take a ref prop or that are defined with React.forwardRef somehow. Do you have an idea how to do that?

@megamaddu
Copy link
Member

I tried to implement it and it got really messy. I'd probably just do it in FFI for now, unless you have an idea how to do it.

@megamaddu
Copy link
Member

The problem was I either needed to add it to every component or duplicate the 3 or 4 component creation function almost exactly but with the ref in the types. Maybe having just one would be better than nothing.. I was hoping I'd come up with a better way to do it.

@i-am-the-slime
Copy link
Member Author

I tried in FFI and I'm not quite there yet. Do you have any leftovers?

@megamaddu
Copy link
Member

megamaddu commented Aug 5, 2020

I don't think I saved the code. The simplest thing would be something like

foreign import mkForwardRefComponent ::
  forall props a.
  String ->
  ({| props } -> Ref a -> JSX) ->
  Effect (ReactComponent { ref :: Ref a | props })
exports.mkForwardRefComponent = (displayName) => (renderFn) => () => {
  const component = (props, ref) => renderFn(props)(ref);
  component.displayName = displayName;
  return React.forwardRef(component);
};

Something like that.. it's a little more complicated if you want hooks

@megamaddu
Copy link
Member

(edited a few times, sorry, I think it works now)

@megamaddu
Copy link
Member

This might work for hooks.. it's a little hacky, haven't tested:

foreign import mkForwardRefComponent ::
  forall props a hooks.
  String ->
  ({| props } -> Ref a -> Render Unit hooks JSX) ->
  Effect (ReactComponent { ref :: Ref a | props })
exports.mkForwardRefComponent = (displayName) => (renderFn) => () => {
  const component = (props, ref) => renderFn(props)(ref)();
  component.displayName = displayName;
  return React.forwardRef(component);
};

@i-am-the-slime
Copy link
Member Author

i-am-the-slime commented Aug 5, 2020

Thanks so much, I was fiddling in parallel and got something to somewhat work. I somehow thought the Ref needed to be typed more like (Nullable (Ref (Nullable Node))) :

foreign import forwardRef 
  :: forall props. 
    EffectFn2 {|props} (Nullable (Ref (Nullable Node))) JSX ->
    ReactComponent { ref :: Nullable (Ref (Nullable Node)) | props }

@megamaddu
Copy link
Member

megamaddu commented Aug 5, 2020

If you use it as a prop to a DOM element it does, but they can be anything. Holding arbitrary values, used with useImperativeHandle (which would be a nightmare to type all on its own 😅), etc

@i-am-the-slime
Copy link
Member Author

Wow, I knew that in general they could be anything, but I assumed that for passing them with forwardRef they'd be monomorphised to Node stuff. Thanks for showing me useImperativeHandle. Alright, I think you're right and I will just write my own FFI in the project itself!

@megamaddu
Copy link
Member

Ok, I think we can just leave this open until it's supported somehow in case anyone else is wondering

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

No branches or pull requests

2 participants