Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a87adef

Browse files
authoredJan 12, 2022
Allow functions to be passed to custom element setters (#23042)
This is part of the new custom element features that were implemented here: 24dd07b When a custom element has a setter for a property and passes the `in` heuristic, the value passed to the react property should be assigned directly to the custom element's property, regardless of the type of the value. However, it was discovered that this isn't working with functions. This patch makes it work with functions. Fixes #23041
1 parent 9a7e6bf commit a87adef

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed
 

‎packages/react-dom/src/__tests__/DOMPropertyOperations-test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,35 @@ describe('DOMPropertyOperations', () => {
504504
expect(customElement.foo).toBe('two');
505505
expect(customElement.getAttribute('foo')).toBe('one');
506506
});
507+
508+
// @gate enableCustomElementPropertySupport
509+
it('custom element properties should accept functions', () => {
510+
const container = document.createElement('div');
511+
document.body.appendChild(container);
512+
ReactDOM.render(<my-custom-element />, container);
513+
const customElement = container.querySelector('my-custom-element');
514+
515+
// Install a setter to activate the `in` heuristic
516+
Object.defineProperty(customElement, 'foo', {
517+
set: function(x) {
518+
this._foo = x;
519+
},
520+
get: function() {
521+
return this._foo;
522+
},
523+
});
524+
function myFunction() {
525+
return 'this is myFunction';
526+
}
527+
ReactDOM.render(<my-custom-element foo={myFunction} />, container);
528+
expect(customElement.foo).toBe(myFunction);
529+
530+
// Also remove and re-add the property for good measure
531+
ReactDOM.render(<my-custom-element />, container);
532+
expect(customElement.foo).toBe(null);
533+
ReactDOM.render(<my-custom-element foo={myFunction} />, container);
534+
expect(customElement.foo).toBe(myFunction);
535+
});
507536
});
508537

509538
describe('deleteValueForProperty', () => {

‎packages/react-dom/src/client/DOMPropertyOperations.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,6 @@ export function setValueForProperty(
184184
}
185185
}
186186

187-
if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
188-
value = null;
189-
}
190-
191187
if (
192188
enableCustomElementPropertySupport &&
193189
isCustomComponentTag &&
@@ -197,6 +193,10 @@ export function setValueForProperty(
197193
return;
198194
}
199195

196+
if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
197+
value = null;
198+
}
199+
200200
// If the prop isn't in the special list, treat it as a simple attribute.
201201
if (isCustomComponentTag || propertyInfo === null) {
202202
if (isAttributeNameSafe(name)) {

0 commit comments

Comments
 (0)
Please sign in to comment.