Skip to content
This repository was archived by the owner on Aug 18, 2025. It is now read-only.

Commit 1b751f8

Browse files
authored
fixing issue with announcer and hot module reloading (#1585)
1 parent 14a66de commit 1b751f8

2 files changed

Lines changed: 43 additions & 37 deletions

File tree

docs/support/media.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ This page contains a list of articles, blogs and newsletters that `react-beautif
3030

3131
## Newsletters
3232

33+
- Tiny letter [November 04, 2019](https://tinyletter.com/cassidoo/letters/the-world-is-changed-by-your-example-not-by-your-opinion-paulo-coelho)
3334
- Ponyfoo [issue 78](https://ponyfoo.com/weekly/78/javascript-and-css-engines-pwa-drag-and-drop-web-components-and-http-2)
3435
- PonyFoo [issue 99](https://ponyfoo.com/weekly/99/react-across-the-universe-typography-load-balancing-and-javascript-frameworks)
3536
- PonyFoo [issue 141](https://ponyfoo.com/weekly/141/http-3-bgp-leaks-react-as-native-dom-typescript-tensorflow-and-all-things-performance)

src/view/use-announcer/use-announcer.js

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// @flow
22
import { useRef, useEffect } from 'react';
33
import { useMemo, useCallback } from 'use-memo-one';
4-
import { invariant } from '../../invariant';
54
import type { Announce, ContextId } from '../../types';
65
import { warning } from '../../dev-warning';
76
import getBodyElement from '../get-body-element';
@@ -14,42 +13,48 @@ export default function useAnnouncer(contextId: ContextId): Announce {
1413
const id: string = useMemo(() => getId(contextId), [contextId]);
1514
const ref = useRef<?HTMLElement>(null);
1615

17-
useEffect(() => {
18-
invariant(!ref.current, 'Announcement node already mounted');
19-
20-
const el: HTMLElement = document.createElement('div');
21-
ref.current = el;
22-
23-
// identifier
24-
el.id = id;
25-
26-
// Aria live region
27-
28-
// will force itself to be read
29-
el.setAttribute('aria-live', 'assertive');
30-
el.setAttribute('role', 'log');
31-
// must read the whole thing every time
32-
el.setAttribute('aria-atomic', 'true');
33-
34-
// hide the element visually
35-
Object.assign(el.style, visuallyHidden);
36-
37-
// Add to body
38-
getBodyElement().appendChild(el);
39-
40-
return () => {
41-
// unmounting after a timeout to let any annoucements
42-
// during a mount be published
43-
setTimeout(function remove() {
44-
const toBeRemoved: ?HTMLElement = ref.current;
45-
invariant(toBeRemoved, 'Cannot unmount announcement node');
46-
47-
// Remove from body
48-
getBodyElement().removeChild(toBeRemoved);
49-
ref.current = null;
50-
});
51-
};
52-
}, [id]);
16+
useEffect(
17+
function setup() {
18+
const el: HTMLElement = document.createElement('div');
19+
// storing reference for usage in announce
20+
ref.current = el;
21+
22+
// identifier
23+
el.id = id;
24+
25+
// Aria live region
26+
27+
// will force itself to be read
28+
el.setAttribute('aria-live', 'assertive');
29+
el.setAttribute('role', 'log');
30+
// must read the whole thing every time
31+
el.setAttribute('aria-atomic', 'true');
32+
33+
// hide the element visually
34+
Object.assign(el.style, visuallyHidden);
35+
36+
// Add to body
37+
getBodyElement().appendChild(el);
38+
39+
return function cleanup() {
40+
// Not clearing the ref as it might be used by announce before the timeout expires
41+
42+
// unmounting after a timeout to let any announcements
43+
// during a mount be published
44+
setTimeout(function remove() {
45+
// not clearing the ref as it might have been set by a new effect
46+
getBodyElement().removeChild(el);
47+
48+
// if el was the current ref - clear it so that
49+
// we can get a warning if announce is called
50+
if (el === ref.current) {
51+
ref.current = null;
52+
}
53+
});
54+
};
55+
},
56+
[id],
57+
);
5358

5459
const announce: Announce = useCallback((message: string): void => {
5560
const el: ?HTMLElement = ref.current;

0 commit comments

Comments
 (0)