🐛 Bug Report
|
selectionManager.replaceSelection(selectedKey); |
Because useTabsListState calls replaceSelection during render which internally calls onSelectionChange the onSelectionChange event handler is called during render.
if (selectionManager.isEmpty || !collection.getItem(selectedKey)) {
selectedKey = collection.getFirstKey();
selectionManager.replaceSelection(selectedKey);
}
For a controlled example I would say we can assume someone will call setState in onSelectionChange to keep track of the currently selected key which causes an error.
Warning: Cannot update a component (`Controls`) while rendering a different component (`Tabs`). To locate the bad setState() call inside `Tabs`, follow the stack trace as described in
🤔 Expected Behavior
I expect to be able to always call setState in event handlers without causing errors.
😯 Current Behavior
I receive an error when doing this.
💁 Possible Solution
Wrap the behavior with a useEffect that sets the first key when no key was set.
🔦 Context
My tabs are generated based on some item that is loaded async. So the initial render of the tabs might be a empty collection with a null selected key. After some time the item is present and the collection is filled. Now I know which key I have to select in a useEffect based on the item (since I cant call setState during render). But onSelectionChange will also be called at this point.
💻 Code Sample
It also does not seem possible to render an empty tabs component here. It will cause an infinite render loop. You can test this by removing the collection.length check.
https://codesandbox.io/s/usetabliststate-mun6z0
🌍 Your Environment
| Software |
Version(s) |
| react-aria |
3.15.0 |
| react-aria |
3.13.0 |
| Browser |
any |
| Operating System |
any |
🧢 Your Company/Team
🕷 Tracking Issue (optional)
🐛 Bug Report
react-spectrum/packages/@react-stately/tabs/src/useTabListState.ts
Line 41 in c38d481
Because
useTabsListStatecallsreplaceSelectionduring render which internally callsonSelectionChangetheonSelectionChangeevent handler is called during render.For a controlled example I would say we can assume someone will call
setStateinonSelectionChangeto keep track of the currently selected key which causes an error.🤔 Expected Behavior
I expect to be able to always call
setStatein event handlers without causing errors.😯 Current Behavior
I receive an error when doing this.
💁 Possible Solution
Wrap the behavior with a
useEffectthat sets the first key when no key was set.🔦 Context
My tabs are generated based on some item that is loaded async. So the initial render of the tabs might be a empty collection with a null selected key. After some time the item is present and the collection is filled. Now I know which key I have to select in a
useEffectbased on the item (since I cant callsetStateduring render). But onSelectionChange will also be called at this point.💻 Code Sample
It also does not seem possible to render an empty tabs component here. It will cause an infinite render loop. You can test this by removing the
collection.lengthcheck.https://codesandbox.io/s/usetabliststate-mun6z0
🌍 Your Environment
🧢 Your Company/Team
🕷 Tracking Issue (optional)