Skip to content

Commit 5e01f9c

Browse files
committed
Skip setting innerHTML when html string has not changed
1 parent 8039f1b commit 5e01f9c

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

packages/react-dom-bindings/src/client/ReactDOMComponent.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,10 @@ function setProp(
565565
);
566566
}
567567
const nextHtml: any = value.__html;
568-
if (nextHtml != null) {
568+
if (
569+
nextHtml != null &&
570+
(prevValue == null || prevValue.__html !== nextHtml)
571+
) {
569572
if (props.children != null) {
570573
throw new Error(
571574
'Can only set one of `children` or `props.dangerouslySetInnerHTML`.',

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

+36
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,42 @@ describe('ReactDOMComponent', () => {
12831283
expect(container.textContent).toEqual('bonjour');
12841284
});
12851285

1286+
it('should set innerHTML when html changed', async () => {
1287+
const container = document.createElement('div');
1288+
const root = ReactDOMClient.createRoot(container);
1289+
await act(() => {
1290+
root.render(<div />);
1291+
});
1292+
const node = container.firstChild;
1293+
const spyOnSetInnerHtml = jest.spyOn(node, 'innerHTML', 'set');
1294+
await act(() => {
1295+
root.render(<div dangerouslySetInnerHTML={{__html: 'bonjour'}} />);
1296+
});
1297+
expect(spyOnSetInnerHtml).toHaveBeenCalledTimes(1);
1298+
await act(() => {
1299+
root.render(<div dangerouslySetInnerHTML={{__html: 'adieu'}} />);
1300+
});
1301+
expect(spyOnSetInnerHtml).toHaveBeenCalledTimes(2);
1302+
});
1303+
1304+
it('should skip setting innerHTML when html did not change', async () => {
1305+
const container = document.createElement('div');
1306+
const root = ReactDOMClient.createRoot(container);
1307+
await act(() => {
1308+
root.render(<div />);
1309+
});
1310+
const node = container.firstChild;
1311+
const spyOnSetInnerHTML = jest.spyOn(node, 'innerHTML', 'set');
1312+
await act(() => {
1313+
root.render(<div dangerouslySetInnerHTML={{__html: 'bonjour'}} />);
1314+
});
1315+
expect(spyOnSetInnerHTML).toHaveBeenCalledTimes(1);
1316+
await act(() => {
1317+
root.render(<div dangerouslySetInnerHTML={{__html: 'bonjour'}} />);
1318+
});
1319+
expect(spyOnSetInnerHTML).toHaveBeenCalledTimes(1);
1320+
});
1321+
12861322
it('should not incur unnecessary DOM mutations for attributes', async () => {
12871323
const container = document.createElement('div');
12881324
const root = ReactDOMClient.createRoot(container);

0 commit comments

Comments
 (0)