-
Notifications
You must be signed in to change notification settings - Fork 17
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
Feature/with react #355
Feature/with react #355
Conversation
0d16d85
to
1b67be0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the Readme.md with a short code sample on how to use it (not in the wiki).
Same style and under the one already existing on how to include WC nativly
src/js/with-react.jsx
Outdated
const { wcNode } = this; | ||
|
||
Object.keys(props).forEach((key) => { | ||
if (key === 'children' || key === 'style') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better an external enum with an array of properties
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and also maybe use this on the property setting on the WC abstract component
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I understand you correctly, that I should put 'children'
and 'style'
into a blacklist array? If so absolutely
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
9529cdf
to
e517479
Compare
@LucaMele |
b8af9d5
to
73f0fa2
Compare
src/demos/todomvc/todo-header.jsx
Outdated
const AXAHeaderMainReact = withReactBound(AXAHeaderMain); | ||
const AXAHeaderLogoReact = withReactBound(AXAHeaderLogo); | ||
|
||
// @todo: super hacky way to keep the input's focus within custom elements |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LucaMele
@TheDadi
I distilled a major problem with reactified custom elements consuming <input>
children from React. Basically on every re-render the focus is lost of the input control, allowing the user to type only one character at a time 😱
The re-rendering of the parent web-component, removes the whole DOM sub tree at first and the re-inserts it again. This causes the loss of the whole browser intrinsic <input>
's state, like:
- focus
- cursor position
- range selection,
- etc.
const Example = (({
onChange,
value,
}) => (
<AXAHeader>
<AXAHeaderMain>
// the following input control will lose focus at every onKeyup/onClick causing a re-render
<input type="text" onChange={onChange} value={value} />
</AXAHeaderMain>
</AXAHeader>
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mmmm.. not good.. what can we do? and why do we re-render? Can we do sort of one-way-binding?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We re-render because on every input's onChange
react's state changes - so React triggers a re-render (which is normal behavior for controlled inputs).
The web-components unfortunately detach completely from the DOM (if you remember the deletion speed test) and attaches a newly generated DOM tree...
So I guess diffing should help us here, but need to verify that...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LucaMele
I found the main glitch. Currently any web-component like <axa-foo bar="baz">
would have even re-rendered if the attribute was set to the exact same value, like:
axaFoo.setAttribute('bar', 'baz'); // no change -> should not trigger re-render, but did before
axaFoo.bar = 'baz'; // no change -> should not trigger re-render, but did before
I fixed this now by checking for shallow equality. And this fixed the input issue too:)
e821346
to
707d178
Compare
Okay that's a super success story, except the |
src/components/m-button/js/button.js
Outdated
const cancelled = fire(this.wcNode, 'axa-click', null, { bubbles: true, cancelable: true, composed: true }); | ||
|
||
if (!cancelled) { | ||
event.preventDefault(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LucaMele
preventDefault
the original event works :)
|
||
handleClick(event, delegateTarget) { | ||
// @todo: would be cool to be able to use props here, cause now it needs JSON.parse... | ||
const index = getAttribute(delegateTarget, 'index'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LucaMele
Passing the current item's data down to the custom event is possible 👍
@LucaMele |
src/js/with-react.jsx
Outdated
|
||
const eventName = dasherize(`${keyFrom2}${key.substring(3)}`); | ||
|
||
eventCache[key] = on(wcNode, eventName, props[key], { passive }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LucaMele
I think it could be convenient to extract the event.detail
here optionally, so that consumers can just deal with the data they need.
const key = camelize(name); | ||
|
||
this[key] = toProp(newValue); | ||
} | ||
|
||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LucaMele
This is suuuper important! It makes sure that the component only re-renders if any attribute has actually changed:)
And it mitigates the nested <input>
issue afore mentioned 🎉
@LucaMele |
I just rebased and it works in chrome with incremental rendering of web-comonents :) |
I created this follow-up issue #418 |
are there any objections for this to merged? |
Fixes #330 .
Changes proposed in this pull request:
withReact
thunkjsx
rosolve, ...)Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Locally
Checklist: