leecade / leecade/react-native-swiper

Exception when reducing number of swiper’s children to 1

Open
#1,284 0 comments 0 reactions 0 assignees View on GitHub

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:

  1. The app must be running on iOS.
  2. It must contain a swiper whose contents change dynamically (i.e., its componentDidUpdate method runs at some time).
  3. The swiper must have the loadMinimal property set to true.
  4. The swiper must initially contain more than one child, and after the change, it must contain exactly one child.
  5. That one child must be provided directly as a third argument to the React.createElement that creates the swiper, in the parent’s render function. Corollary: you must not use JSX, which always ensures that children is 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:

  1. Clone the above repo
  2. Run yarn ios
  3. 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.