-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
CommandBar: componentRefs get wiped out when resizing/re-rendering #7582
Comments
I debugged into this, and found the culprit. @christiango for visability. In your codepen, you're calling this.setState({}), which causes new items to be created and passed into the CommandBar. I debugged that just re-rendering your content component would cause the ref to become invalidated with a new button ref, and then it would clear it out with null. Here's why! The CommandBar interprets these as new, unmeasured items. They end up getting passed along to ResizeGroup, which will try to re-render and measure the items. The componentRef is then evaluated again because of the offscreen render, which resets the ref to the wrong, offscreen button. Then once resizegroup is done measuring, it removes the button, killing the ref. There are 2 questions I have:
|
Micah and I prototyped #2. Overall it would fix some, but not all, scenarios where componentRef could be used. For example, buttons can have menu items, which each might have sub sub sub menus, which may have items that have componentRefs to things rendered in the ResizeGroup. So, I think we need to question if ResizeGroup really needs the "offscreen" render, or if so, is there any contextual way to not resolve componentRefs in this case. I would really prefer to avoid adding a ContextProvider to BaseComponent. The new |
What if we did all our rendering onscreen to avoid redundant rendering? would there be flicker? Would IntersectionObserver help here? |
I do believe we were seeing a flicker on older browsers when doing the measurement on screen, but Micah was the first one to experiment with off screen rendering, so he might know more details. With respect to your question David, ResizeGroup doesn't measure individual buttons, it measures the width of the entire group of buttons. |
Is there a way to clone the current DOM (excluding refs) and display that while the original control resizes? No clue how technically possible that is, but it'd be a different way to approach the problem. |
Sorry, I accidentally closed this. I think we would have to go outside React to do the kind of thing you are suggesting. |
I had thought about potentially using renderToString.. but I think that would bloat bundle sizes. I suspect that the solution of filtering out componentRef for offscreen renders might be just good enough. We aren't rendering button menus or anything, so those would not be evaluated. |
@micahgodbolt or @christiango wanna take a stab here? I'm going to try and fix the focuszone focus restore issue. |
I won't be able to help out here unfortunately. I am currently not working on UX to help us with some Word deliverables. |
I can get some eyes from our team to help test the change against the Ribbon if we think there is a regression risk |
This goes beyond "componentRefs", it also makes getting html refs to elements rendered within a resize group impractical. For example, we are using teaching tips to point to elements and we have been trying to use element refs rather than selectors but these refs are not stable and are often set to null when the element is rendered in a resize group due to the reasons set above. We will likely be forced to use selectors instead, but there are reasons why we would prefer to use element refs, so if there is a way to prevent them from being nulled out with off-screen rendering, that would be great. |
Because this issue has not had activity for over 150 days, we're automatically closing it for house-keeping purposes. Still require assistance? Please, create a new issue with up-to date details. |
I am trying to use Calendar component with a Callout inside a Commandbar. By default the Calendar component does not auto close on selection and for that reason I call the dismissMenu() function on onSelectDate() of Calendar. But there is some issue around the setting of the ref. Its gets set only once and the second time it comes as null. If I give a unique key to the CommandBar (i.e force react to mount the whole CommandBar everytime then it works)
Environment Information
Please provide a reproduction of the bug in a codepen:
https://codepen.io/nikhilpuria/pen/PXaaVP?editors=1010
Expected behavior:
componentRef is called only once
Actual behavior:
componentRef should be called everytime the component is rendered
Priorities and help requested:
Are you willing to submit a PR to fix? (Yes, No)
Requested priority: (Blocking, High, Normal, Low)
Products/sites affected: (if applicable)
The text was updated successfully, but these errors were encountered: