callstack / callstack/react-native-pager-view

NSInternalInconsistencyException crashes app

Offen
#507 6 Kommentare 3 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
TypeScript
Sterne
3.4k
Forks
476
Ø Merge
10 T. 21 Std.
Gemergte PRs (30 T.)
2

Beschreibung

## Environment

iOS

## Description

I have some fairly simple code that populates pages and then navigates to one of them. For some reason, if I am generating more than 20/30 pages on iOS, the app crashes with:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unexpected view controller: '

## Reproducible Demo

I populate maybe 20 pages, and then elsewhere in the app, asynchronously navigate to a page somewhere towards the end (but after the pages in theory have been populated). I can see for a split second that it's trying to land on a page that doesn't yet exist, then it crashes. I guess that it's trying to access this screen before it has time to generate it. Oddly, using a setTimeout to access the page does not help. I call the page with `setPage` on the ref.

The code of the component in question:

```
type Props = {
// Should always be in order
dates: SliderDate[]
onDateSelect: (date: Date) => void
}

function sliceIntoChunks(arr: any[], chunkSize: number) {
const res = []
for (let i = 0; i < arr.length; i += chunkSize) {
const chunk = arr.slice(i, i + chunkSize)
res.push(chunk)
}

return res
}

export const DateSlider = (props: Props) => {
const [weeks, setWeeks] = useState([])

const getWeeks = (dates: SliderDate[]): SliderDate[][] => {
const weekResult: SliderDate[] = []

/// Fill with blank dates
const dateTicker = new Date()
dateTicker.setHours(0, 0, 0, 0)
dateTicker.setDate(dateTicker.getDate() - 100) // <--- breaks it
// dateTicker.setDate(dateTicker.getDate() - 10) // <- this one is ok

// find closest monday
while (dateTicker.getDay() !== 1) {
dateTicker.setDate(dateTicker.getDate() + 1)
}

console.log("got here")
for (let i = -10; i < 30; i++) {
// console.log(dateTicker.getDay())
if (dateTicker.getDay() !== 0 && dateTicker.getDay() !== 6) {
weekResult.push({
date: new Date(dateTicker),
selected: false,
recurring: false,
ordered: false,
disabled: true,
})
}

dateTicker.setDate(dateTicker.getDate() + 1)
}

while (weekResult.length % 5 !== 0) {
console.log("got here2", weekResult.length)

if (dateTicker.getDay() !== 0 && dateTicker.getDay() !== 6) {
weekResult.push({
date: new Date(dateTicker),
selected: false,
recurring: false,
ordered: false,
disabled: true,
})
}

dateTicker.setDate(dateTicker.getDate() + 1)
}

/// Overwrite with dates from props
for (const date of props.dates) {
const realIndex = weekResult.findIndex(day => {
return day.date.toISOString() === date.date.toISOString()
})

weekResult[realIndex] = date
}

return sliceIntoChunks(weekResult, 5)
}

useEffect(() => {
const newWeeks = getWeeks(props.dates)
setWeeks(newWeeks)

const idx = newWeeks.findIndex(week => {
return !!week.find(day => day.selected)
})
if (idx < newWeeks.length) {
setTimeout(() => {
// @ts-ignore
pagerRef.current!.setPage(idx)
}, 500)
}
}, [props.dates])
const pagerRef = useRef(null)

return (


{weeks.map(week => {
return (







)
})}


)
}
```

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne mit der PagerView-Referenz der DateSlider-Komponente und dem asynchronen setPage-Aufruf. Reproduziere das Problem anschließend auf iOS mit mehr als 20 Seiten und setze dateTicker auf 100 Tage statt auf 10 zurück. Vergleiche die generierte Seitenanzahl und das Timing der Navigation; die Aufgabe ist erledigt, wenn die Navigation zur ausgewählten Seite keine NSInternalInconsistencyException mehr auslöst.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
ios, react-native, typescript
Bereich
mobile
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Veraltet
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.