purescript-react-basic-hooks
purescript-react-basic-hooks copied to clipboard
How to `forwardRef`?
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?
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.
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 tried in FFI and I'm not quite there yet. Do you have any leftovers?
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
(edited a few times, sorry, I think it works now)
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);
};
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 }
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
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!
Ok, I think we can just leave this open until it's supported somehow in case anyone else is wondering