Skip to content

Commit 257d90f

Browse files
committed
Refactor shouldSetTextContent & add tests (#11789)
1 parent d9869a4 commit 257d90f

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

packages/react-dom/src/__tests__/ReactDOMTextComponent-test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,16 @@ describe('ReactDOMTextComponent', () => {
197197
expect(el.textContent).toBe('');
198198
});
199199

200+
it('can reconcile text from pre-rendered markup using dangerouslySetInnerHTML and an object with toString', () => {
201+
const HelloObject = {toString: () => 'Hello'};
202+
const el = document.createElement('div');
203+
let reactEl = <p dangerouslySetInnerHTML={{__html: HelloObject}} />;
204+
el.innerHTML = ReactDOMServer.renderToString(reactEl);
205+
206+
ReactDOM.hydrate(reactEl, el);
207+
expect(el.textContent).toBe('Hello');
208+
});
209+
200210
xit('can reconcile text arbitrarily split into multiple nodes', () => {
201211
const el = document.createElement('div');
202212
let inst = ReactDOM.render(

packages/react-dom/src/client/ReactDOM.js

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -667,14 +667,36 @@ const DOMRenderer = ReactFiberReconciler({
667667
},
668668

669669
shouldSetTextContent(type: string, props: Props): boolean {
670-
return (
671-
type === 'textarea' ||
670+
if (type === 'textarea') {
671+
return true;
672+
}
673+
674+
if (
672675
typeof props.children === 'string' ||
673-
typeof props.children === 'number' ||
674-
(typeof props.dangerouslySetInnerHTML === 'object' &&
675-
props.dangerouslySetInnerHTML !== null &&
676-
typeof props.dangerouslySetInnerHTML.__html === 'string')
677-
);
676+
typeof props.children === 'number'
677+
) {
678+
return true;
679+
}
680+
681+
if (
682+
typeof props.dangerouslySetInnerHTML === 'object' &&
683+
props.dangerouslySetInnerHTML !== null
684+
) {
685+
if (typeof props.dangerouslySetInnerHTML.__html === 'string') {
686+
return true;
687+
}
688+
689+
if (props.dangerouslySetInnerHTML.__html === null) {
690+
return false;
691+
} else if (
692+
typeof props.dangerouslySetInnerHTML.__html === 'object' &&
693+
typeof props.dangerouslySetInnerHTML.__html.toString === 'function'
694+
) {
695+
return true;
696+
}
697+
}
698+
699+
return false;
678700
},
679701

680702
shouldDeprioritizeSubtree(type: string, props: Props): boolean {

packages/react-dom/src/client/__tests__/dangerouslySetInnerHTML-test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,14 @@ describe('dangerouslySetInnerHTML', () => {
9191
expect(circle.tagName).toBe('circle');
9292
});
9393
});
94+
95+
it('when rendering an object with a toString method', () => {
96+
const container = document.createElement('div');
97+
const HelloObject = {toString: () => 'Hello'};
98+
const node = ReactDOM.render(
99+
<div dangerouslySetInnerHTML={{__html: HelloObject}} />,
100+
container,
101+
);
102+
expect(node.textContent).toBe('Hello');
103+
});
94104
});

0 commit comments

Comments
 (0)