Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate and remove useFocusZone dependency array #5450

Open
iansan5653 opened this issue Dec 16, 2024 · 3 comments
Open

Deprecate and remove useFocusZone dependency array #5450

iansan5653 opened this issue Dec 16, 2024 · 3 comments
Assignees
Labels
enhancement New feature or request react

Comments

@iansan5653
Copy link
Contributor

useFocusZone accepts an uncommon optional second argument: an array of dependencies. While comparable to the dependency arrays passed to other React hooks, the optionality and unlinted nature of this argument make it easy to forget about or incorrectly configure. I have personally introduced a few bugs because I didn't know this argument needed to be considered.

I think with modern JavaScript this array is probably wholly unnecessary. All options passed to useFocusZone through the options object can easily be included as dependencies by using a shallow comparison. The trickier part is for the hook to know when the contents of the container element change, but this can now relatively easily be achieved by using a MutationObserver on the parent.

With MutationObserver, the dependencies array could be totally removed. This would simplify the API and clear up a potential footgun.

@lesliecdubs lesliecdubs added the enhancement New feature or request label Dec 17, 2024
@lesliecdubs
Copy link
Member

lesliecdubs commented Dec 23, 2024

Thanks for filing, @iansan5653! Things are a bit quiet though the holidays, so I'm going to leave this in the Primer inbox to discuss with the team in the new year to see how we might be able to move this forward.

Open question: would this be a breaking change?

@hectahertz hectahertz self-assigned this Feb 21, 2025
@hectahertz
Copy link
Contributor

Hi @iansan5653, thanks for reporting this and for the suggestions.

Could you please share in which cases you've encountered bugs with this approach? It would help us decide where we want to go with this.

The way it is designed right now, it assumes you won't use the dependency array unless there is an explicit need to reset the zone.

I'm afraid if we were to implement this using a MutationObserver we could run into situations where we reset when we shouldn't, but I'd like to hear your thoughts.

@iansan5653
Copy link
Contributor Author

The way it is designed right now, it assumes you won't use the dependency array unless there is an explicit need to reset the zone.

The problem with this approach is that it assumes by default that the contents of the zone will never change - that items will never be added, removed, or reordered. This runs contrary to the React philosophy of being reactive to changes. I think any use of useFocusZone without the dependency array is potentially buggy because contents of React components can always be assumed to be changing by default. But even with the dependency array it's difficult to ensure there are no bugs because this array is not lintable like the dependencies of hooks and memos.

MutationObserver is a logical solution because what we really care about is detecting DOM changes and updating the zone accordingly.

I'm afraid if we were to implement this using a MutationObserver we could run into situations where we reset when we shouldn't, but I'd like to hear your thoughts.

I think it wouldn't be too difficult to bail out in cases that don't require a reset. It's relatively inexpensive (performance-wise) to generate the list of elements involved in the zone. Then we can simply do a shallow comparison to see if any elements were added/removed/reordered, and only reset the zone in these cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request react
Projects
None yet
Development

No branches or pull requests

3 participants