Last active
December 23, 2020 07:48
-
-
Save DimitryDushkin/c091d5a6c33e10641eef0828261d5398 to your computer and use it in GitHub Desktop.
React v15 Shadow Dom events fix. Based on http://stackoverflow.com/a/37891448/297939. Unnecessery events removed and fix for multiple dispatches added.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default function retargetEvents(el) { | |
// Here include necessary events' name to track | |
['onClick', 'onChange'].forEach(eventType => { | |
const transformedEventType = eventType.replace(/^on/, '').toLowerCase(); | |
el.addEventListener(transformedEventType, event => { | |
for (let i in event.path) { | |
const item = event.path[i], | |
internalComponent = findReactInternal(item); | |
if (internalComponent && internalComponent._currentElement && internalComponent._currentElement.props) { | |
dispatchEvent(event, eventType, internalComponent._currentElement.props); | |
} | |
if (item == el) { | |
break; | |
} | |
} | |
}); | |
}); | |
} | |
function findReactInternal(item) { | |
let instance; | |
for (let key in item) { | |
if (item.hasOwnProperty(key) && ~key.indexOf('_reactInternal')) { | |
instance = item[key]; | |
break; | |
} | |
} | |
return instance; | |
} | |
function dispatchEvent(event, eventType, itemProps) { | |
if (itemProps[eventType]) { | |
itemProps[eventType](event); | |
} | |
} | |
// ========================================================================= | |
// index.js (mounting point of React) | |
import { render } from 'react-dom'; | |
import App from './App.jsx'; | |
import retargetEvents from './react-shadow-dom-fix.js'; | |
const shadowRoot = document.querySelector('#ydf-cs-helper').createShadowRoot(), | |
appContainer = document.createElement('div'); | |
shadowRoot.appendChild(appContainer); | |
render(<App />, appContainer); | |
// use the fix above | |
retargetEvents(shadowRoot); |
A workaround would be to listen to onInput
instead of onChange
. We might event shim this and call onChange
when onInput
is triggered
I just did that and it works great. Updated and published my npm package
https://www.npmjs.com/package/react-shadow-dom-retarget-events
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@awwester this is the proper native behavior, the browser fires the onChange event when the input is blurred, so technically it's correct. React works differently however and I have no idea yet how to fix it.
facebook/react#10422 (comment)