New containerElements option doesn't lend itself to React
See original GitHub issueMy scenario: I want to limit focus to the child of FocusTrap
, and a set of CSS selectors. Here’s what my code has to look like:
export const MyFocusTrap = props => {
const ref = React.useRef();
const [dummy, setDummy] = React.useState();
React.useEffect(() => {
setDummy(Math.random());
}, []);
// `array` is my own array utils library.
const elts = array.compact(array.flatten([
props.containerCss.map(s => Array.from(document.querySelectorAll(s))),
ref.current
]));
return (
<FocusTrapReact containerElements={elts}>
<div ref={ref}>{props.children}</div>
</FocusTrapReact>
);
};
The issues I see are:
- In order to include the child, I have to use a ref. I don’t want that
div
to exist at all. - Because the ref is necessary, I have to use dummy state to force the component to render twice on mount. Otherwise, the ref wouldn’t be added to the elements list. This is the biggest issue, because it causes a potentially significant performance hit.
containerElements
must be HTMLElements, not selectors, so I have to do a lot of extra work to get them into the right format.
Issue Analytics
- State:
- Created 3 years ago
- Comments:13 (9 by maintainers)
Top Results From Across the Web
Leveling Up With React: Container Components - CSS-Tricks
React wants to flow data in a way that just doesn't lend itself well to how traditional models work. The Flux design pattern,...
Read more >Show or hide element in React - Stack Overflow
If the state variable is null and the component is visible then have the render function return a placeholder. Otherwise render the data....
Read more >Refs and the DOM - React
Refs provide a way to access DOM nodes or React elements created in the render method. In the typical React dataflow, props are...
Read more >ReactDOM – React
Render a React element into the DOM in the supplied container and return a reference to the component (or returns null for stateless...
Read more >Uncontrolled Components - React
In React, an <input type="file" /> is always an uncontrolled component because its value can only be set by a user, and not...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
You could do what I did, and convert selectors to elements each time you need the data, but I understand your reasoning for avoiding that.
I used an observer and a custom hook to add and remove trapped elements. I thought of going the context route, but I felt like that would add too much of a structural requirement to components. It’s probably the way to go if you want to integrate it into
focus-trap-react
.I’m not sure why you’re seeing 4 renders in your sandbox. I added a console.log(), and only got two outputs. Then I changed the global counter to a ref, and the UI displayed 2. So I think you get the same number of renders using the React and non-React version.
Anyway, should this ticket be closed?
Alright, thanks again, closing.