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

Support react 16 (quick way) #11

Merged
merged 11 commits into from
Oct 24, 2017
Merged

Support react 16 (quick way) #11

merged 11 commits into from
Oct 24, 2017

Conversation

ngryman
Copy link
Contributor

@ngryman ngryman commented Oct 20, 2017

This PR takes the fastest path to support React 16 with one breaking change: the domNode passed to the component is already mutated so referring to its textContent will not work anymore.

I've skipped the associated test for now and wait for opinions on how to handle this.

cc @jdeal @vitorbal
ref #10

@jdeal
Copy link
Contributor

jdeal commented Oct 20, 2017

@ngryman Can you describe why the breaking change occurs?

@jdeal
Copy link
Contributor

jdeal commented Oct 20, 2017

It seems like this just keeps using the unstable API and so avoids the breaking change?

@ngryman
Copy link
Contributor Author

ngryman commented Oct 20, 2017

@jdeal Fixed the CI to highlight the issue: https://travis-ci.org/zapier/react-element-portal/builds/290528365#L1499

@jdeal
Copy link
Contributor

jdeal commented Oct 20, 2017

I see now @ngryman. That's definitely a breaking change. I think we'll want to allow passing in a callback instead. So something like:

const Greeting = ({textContent}) => (<div>Hello {textContent}</div>);
const mapDomNodeToProps = (domNode) => ({
  textContent: domNode.textContent
});
render(
  <div>
    <ElementPortal selector="li.greeting" view={Greeting} mapDomNodeToProps={mapDomNodeToProps}/>
  </div>,
  document.getElementById(appId)
);  

That way we can call the callback before we render, similar to how we grab props from dataset. Effectively, dataset will become the preferred way to pass data, and mapDomNodeToProps will be a way to customize that.

@ngryman
Copy link
Contributor Author

ngryman commented Oct 20, 2017

@jdeal Yeah I've thought about that and it's the better compromise I think. If we're doing so, why not having only this callback and deprecate the data attribute?

@jdeal
Copy link
Contributor

jdeal commented Oct 20, 2017

@ngryman I'm okay with that, but I do feel like the data attribute is pretty handy here and feels like a good recommended approach for passing data. Of course, it's also wasted cycles if you have a lot of attributes you don't use. But I don't know if that's a huge concern here. I'm kinda torn. Maybe we add mapDomNodeToProps and hold off on the data decision for now? We could export a helper I guess for that purpose too. I wouldn't want to force the dataset boiler-plate out to userland.

@ngryman
Copy link
Contributor Author

ngryman commented Oct 23, 2017

mapDomNodeToProps was what I was thinking, it gives lots of flexibility to the user while removing complexity our side.

I'm okay with that, but I do feel like the data attribute is pretty handy here and feels like a good recommended approach for passing data.

With the introduction of mapDomNodeToProps, the user now has a generic way of extracting data from the pre-existing target node and pass it to the transported component.
IMHO, keeping the data attribute would be redundant and opinionated here. If the user needs to parse data attributes, then he could use a utility package for that (https://github.com/rafaelrinaldi/data-attributes):

import dataAttributes from 'data-attributes'

const mapDomNodeToProps = (node) => ({
  data: dataAttributes(node)
})

<ElementPortal selector=".target" view={Component} mapDomNodeToProps={mapDomNodeToProps} />

Breaking change: The new way of passing data from the target node to the transported component is implemented via the mapDomNodeToProps function that takes the target node as input and binds the output object to the transported component.
@jdeal
Copy link
Contributor

jdeal commented Oct 23, 2017

@ngryman I'm cool with that change, but can you replace the current data example in the README with your snippet using the data-attributes module? And we should probably publish this as 1.0.0?

Let bundlers use the source instead of the pre-bundled version. Also very helpful for ad-hoc testing.
@ngryman
Copy link
Contributor Author

ngryman commented Oct 23, 2017

I've updated the docs, please correct/enhance my English :)

While patching zapier/zapier to check things work correctly (and it works btw 🎉), I think we could take the chance to change the API a little bit for something a little more concise. Nothing really fancy, just some tweaks that I'm gonna put in a PR tomorrow.

Meanwhile, if you think everything is ok for the React 16 migration, please tell me so I can reference it in zapier/zapier and ask for a review there.

Copy link
Contributor

@jdeal jdeal left a comment

Choose a reason for hiding this comment

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

@ngryman A couple small wording tweaks, but otherwise we're good!

README.md Outdated
`ElementPortal` also accepts an optional `view` prop that takes a component, to be rendered inside the portal:

```js
<ElementPortal id="header" view={CoolHeaderComponent} />
```

One advantage of using the `view` prop to specify a component is that any `data-` attributes from the DOM node the portal is rendering to will be passed along to our component as a `data` prop.
For example, if the DOM node we are rendering to looks like this:
One advantage of using the `view` prop to the ability to derive properties from the original DOM node to the the component.
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably want something like:

One advantage of using the view prop is the ability to derive properties from the original DOM node and pass them to the the component.

README.md Outdated
)
```

By using the `mapDomNodeToProps` you can easily pass this data like so:
Copy link
Contributor

Choose a reason for hiding this comment

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

Small tweak here:

By using the mapDomNodeToProps prop, you can easily pass this data like so:

@ngryman ngryman merged commit 5a60663 into master Oct 24, 2017
@ngryman ngryman deleted the react-16-quick branch October 24, 2017 09:41
@ngryman ngryman mentioned this pull request Jan 2, 2018
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

Successfully merging this pull request may close these issues.

None yet

2 participants