question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

New containerElements option doesn't lend itself to React

See original GitHub issue

My 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:

  1. In order to include the child, I have to use a ref. I don’t want that div to exist at all.
  2. 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.
  3. 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:closed
  • Created 3 years ago
  • Comments:13 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
ziothcommented, Nov 18, 2020

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?

0reactions
stefcameroncommented, Nov 18, 2020

Alright, thanks again, closing.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found