TypeError: Cannot read property 'start' of undefined
See original GitHub issueBug Report
Describe the Bug
Abstract list components receives rows as props. useVirtual() is used in this component.
Filtering (i.e. truncating) rows in parent component leads to TypeError: Cannot read property 'start' of undefined
,
but only if original/longer list was scrolled down a page or so before filtering.
How to Reproduce
Steps to reproduce the behavior, please provide code snippets or a repository:
Usage
The error show a little less frequent, when entries
are managed as local state (commented out below).
resetScroll
seems to have no impact on error condition.
const entries = props.entries
// const [entries, setEntries] = React.useState(props.entries)
// React.useEffect(() => {
// setEntries(props.entries)
// }, [props.entries])
const { outerRef, innerRef, items, scrollToItem } = useVirtual({
itemCount: entries.length,
resetScroll: true
})
Steps to reproduce in CodeSandbox (provided below):
- Display 800 list rows
- Scroll down a page or more
- Shorten list to 2 rows (combo box)
4.
TypeError: Cannot read property 'start' of undefined
@var currStart = msData[vStop].start;
In case entries are managed as state in <List/>
4. Repeat steps 1, 2 and 3
5. TypeError: Cannot read property 'start' of undefined
@ var currStart = msData[vStop].start;
The primary problems seems to be that items
array is often ‘overshooting’, i.e. not in sync with rows/entries, items
length exceeds rows
length. In this case I can only return null
as a result:
const card = ({ index, measureRef }) => {
// Why can this happen?
if (index >= entries.length) {
console.warn('<List/> overshooting', `${index}/${entries.length}`)
return null
}
const entry = entries[index]
return child({
entry,
id: entry.id,
focused: focusId === entry.id,
selected: selected.includes(entry.id),
ref: measureRef
})
}
CodeSandbox Link
https://codesandbox.io/s/keen-thunder-e0f5m
Expected Behavior
Don’t crash and burn, when list is filtered in parent.
Your Environment
- MacBook Pro (15-inch, 2017)
- macOS 11.5.2 (Big Sur)
- Electron 13.1.6
process.versions = {
"node": "14.16.0",
"v8": "9.1.269.36-electron.0",
"uv": "1.40.0",
"zlib": "1.2.11",
"brotli": "1.0.9",
"ares": "1.16.1",
"modules": "89",
"nghttp2": "1.41.0",
"napi": "7",
"llhttp": "2.1.3",
"openssl": "1.1.1",
"icu": "68.1",
"unicode": "13.0",
"electron": "13.1.6",
"chrome": "91.0.4472.124"
}
Additional Information
Scrolling down the 800 row list from CodeSandbox in Safari frequently show the following error message in console (without stack trace): [Error] ResizeObserver loop completed with undelivered notifications. (x17)
But Safari is NOT the target environment! Might be helpful anyway.
Issue Analytics
- State:
- Created 2 years ago
- Comments:10 (4 by maintainers)
Top GitHub Comments
@wellyshen Got it! I leave it as is for now. The list model is managed two levels up in the component hierarchy and I’m reluctant to pull useVirtual() this far up. Many thanks for your help! ❤️
@dehmer It’s because the
rows
prop is updated before the items of the hook. So you encounter the race condition of the states between the app component and the hook. You can keep the error handling or maintain the full rows data for your case.