leecade / leecade/react-native-swiper
Exception when reducing number of swiper’s children to 1
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 10.5k
- Forks
- 2.3k
- PR merge metrics
- No merged PRs in 30d
Description
Which OS ?
iOS
Version
Which versions are you using:
- react-native-swiper v1.6.0
- react-native v0.64.0
Prerequisites
The bug only manifests itself in rare circumstances. Specifically, all of the following must be true:
- The app must be running on iOS.
- It must contain a swiper whose contents change dynamically (i.e., its
componentDidUpdatemethod runs at some time). - The swiper must have the
loadMinimalproperty set totrue. - The swiper must initially contain more than one child, and after the change, it must contain exactly one child.
- That one child must be provided directly as a third argument to the
React.createElementthat creates the swiper, in the parent’s render function. Corollary: you must not use JSX, which always ensures thatchildrenis an array.
Expected behaviour
Upon change, the swiper should update properly to display the only page.
Actual behaviour
When all of these circumstances are true, upon change of the swiper’s contents, a warning pops up:
Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.
and at that point, the swiper either disappears altogether or wreaks havoc upon subsequent attempts to swipe.
How to reproduce it
I’ve prepared a minimal example that reproduces the bug.
Steps to reproduce:
- Clone the above repo
- Run
yarn ios - In the app, click the black Kaboom button.
I’ve also made an Expo snack with the same code. Unfortunately, the iOS Expo runner seems to disable YellowBox, so it’s better to run the above example directly in the simulator.
The cause
react-native-swiper looks at the total value in the state to determine if it has more than one element. If total > 1, it assumes that this.props.children is an array (or at least indexable), and it then plucks out individual elements when converting children to pages.
However, under the circumstances described above, it fails to update total when the only child is passed. The culprit seems to be this check. I’m not sure what was the rationale behind it, so don’t know what the best fix is.
The workaround
For now, the workaround in my app is to disable loadMinimal. Without it, the swiper works as expected.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at src/index.js around the check at line 229, focusing on how total and children are updated when loadMinimal is true and one child is passed directly. Reproduce with the linked minimal example's App.js by running yarn ios and pressing the Kaboom button. Done means the swiper displays its single page without the warning and remains usable for swiping.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react-native
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100