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

Add support for createRef API #172

Merged
merged 11 commits into from
Aug 10, 2019
Merged

Conversation

elliotdavies
Copy link
Contributor

@elliotdavies elliotdavies commented Jul 1, 2019

Fixes #167 by adding support for React's createRef API. Also distinguishes between DOM refs and React instance refs.

I've created a branch of purescript-react-example to showcase the different combinations of props, callbacks and ref types (see here in particular).


The ReactInstance type probably isn't in the right place; I can move it somewhere else. (React.purs feels better but that causes an import cycle.)

Otherwise the only thing I dislike is having to check ref.current to see whether the item is a ref, or an object with the shape { current: <ref> } (see https://reactjs.org/docs/refs-and-the-dom.html#accessing-refs). I'm not sure I see a way around this, though.

@ethul
Copy link
Contributor

ethul commented Jul 3, 2019

Thanks for your PR! I will have to dig into this, might take me a bit of time. Apologies for that, but I will get to it.

Copy link

@Shou Shou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice work, just one small bug

src/React/Ref.js Outdated Show resolved Hide resolved
Copy link
Member

@LiamGoodacre LiamGoodacre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, just a quick note on the getCurrentRef_ impl.

src/React/Ref.js Outdated Show resolved Hide resolved
@@ -20,6 +19,7 @@ import React.SyntheticEvent
, SyntheticUIEvent
, SyntheticWheelEvent
)
import Web.HTML.HTMLElement (HTMLElement)
Copy link
Contributor

@ethul ethul Jul 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a quick note. This is coming from purescript-web-html, but I didn't notice the dependency in the bower file. Is it being pulled in from another dependency?

On this note, I am unsure if we want this as a dependency since runtimes like react native, etc., would not necessarily require it. So far we have been attempting to keep dependencies at a minimum. That being said, I am not completely opposed to adding the dependency, but wanted to open it up for discussion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ethul Well spotted; I think I forgot to push the change to the bower file. I had added "purescript-web-html": "^2.2.0" locally.

I suppose that we could have a local HTMLElement type here and not use the library version. It would save on the dependency, but on the other hand anyone using DOM refs would have to write a conversion function (i.e. unsafeCoerce), which might be annoying.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the dependency.

@@ -894,8 +894,8 @@ onScrollCapture f = unsafeMkProps "onScrollCapture" (mkEffectFn1 f)
onWheelCapture :: (SyntheticWheelEvent -> Effect Unit) -> Props
onWheelCapture f = unsafeMkProps "onWheelCapture" (mkEffectFn1 f)

ref :: (Nullable ReactRef -> Effect Unit) -> Props
ref f = unsafeMkProps "ref" (mkEffectFn1 f)
ref :: Ref.RefHandler HTMLElement -> Props
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this always HTMLElement here? For example, on React Native, would this be something different?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. I haven't used React Native myself, but I looked into this and as far as I can tell Native doesn't have refs - it seems to use something called Direct Manipulation instead. This does raise the question of why the React team put refs in the React library instead of ReactDOM; I'm not sure what the answer is.

@ethul
Copy link
Contributor

ethul commented Aug 2, 2019 via email

@elliotdavies
Copy link
Contributor Author

@ethul Hmm, after a closer reading of that docs page I think you're correct. I would guess that ReactInstance is correct across web/native for a ref on a custom component, but presumably you get either a DOM node or some sort of native element node if you use a ref on a web/native primitive. In that case do you think it's best to have something like

ref :: Ref.RefHandler PrimitiveNode -> Props

and let the user coerce it as they see fit? This would also avoid theweb-html dependency. (Open to suggestions for a decent type name here!)

@ethul
Copy link
Contributor

ethul commented Aug 2, 2019 via email

@elliotdavies
Copy link
Contributor Author

@LiamGoodacre I've updated the FFI implementation such that callback refs are lifted into an object like { current: ref }, thereby making the .current property access safe.

@ethul I've updated the types to use NativeNode and removed the HTMLElement import. I think the React Native use case is compelling enough to go down this route.

src/React/Ref.purs Outdated Show resolved Hide resolved
@ethul
Copy link
Contributor

ethul commented Aug 10, 2019

Thanks so much for making these updates. Looking great!

@elliotdavies
Copy link
Contributor Author

@ethul No problem! Anything else you'd like doing to this before we can get it merged?

@ethul
Copy link
Contributor

ethul commented Aug 10, 2019

Thanks! All looks good to me

@ethul ethul merged commit 4bf5a5a into purescript-contrib:master Aug 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Add support for createRef
4 participants