I'm very new to React Native and I'm trying to use this component: https://github.com/archriss/react-native-snap-carousel
I tried using that code they provided in the usage portion to create the simplest working version:
return (
<Carousel
ref={(c) => { this._carousel = c; }}
data={this.state.entries} // this seems to be the problem
renderItem={this._renderItem}
sliderWidth='100%'
itemWidth='80%'
/>
);
Where "entries" is an array. This results in the following error:
Invariant Violation: inputRange must be monotonically increasing NaN,NaN,NaN
Edit: Here's the _renderItem method
_renderItem ({item, index}) {
return (
<View style={styles.slide}>
<Text style={styles.title}>{ item.title }</Text>
</View>
);
}
If you dig in further into react-native source code, you can find the error source in file AnimatedInterpolation.js
where it expects inputRange for interpolation to be an array of numbers. So my best guess is react-native-snap-carousel uses itemWidth
value to calculate interpolation's data and pass it to react-native's Animated component. You can find that implementation in here. If you provide a non-integer value to itemWidth
, the calculation will always return NaN, creating that error.
Short answer: replace itemWidth
with a actual number.
UPDATE 16 Jan 2020: newer version of react-native changes the message, so I updated the links accordingly and added original code:
Handler inside AnimatedInterpolation.js
(react-native v0.61.5)
function checkValidInputRange(arr: Array<number>) {
invariant(arr.length >= 2, 'inputRange must have at least 2 elements');
for (let i = 1; i < arr.length; ++i) {
invariant(
arr[i] >= arr[i - 1],
/* $FlowFixMe(>=0.13.0) - In the addition expression below this comment,
* one or both of the operands may be something that doesn't cleanly
* convert to a string, like undefined, null, and object, etc. If you really
* mean this implicit string conversion, you can do something like
* String(myThing)
*/
'inputRange must be monotonically non-decreasing ' + arr,
);
}
}
Function using sliderWidth
and pass to inputRange
in react-native-snap-carousel (v3.8.4)
_initPositionsAndInterpolators (props = this.props) {
const { data, itemWidth, itemHeight, vertical } = props;
const sizeRef = vertical ? itemHeight : itemWidth; // USAGE
// ...
this._getCustomData(props).forEach((itemData, index) => {
const _index = this._getCustomIndex(index, props);
const start = (_index - 1) * sizeRef; // HERE
const middle = _index * sizeRef; // HERE
const end = (_index + 1) * sizeRef; // AND HERE
const animatedValue = this._shouldAnimateSlides(props) ? this._scrollPos.interpolate({
inputRange: [start, middle, end],
outputRange: [0, 1, 0],
extrapolate: 'clamp'
}) : 1;
this._positions[index] = {
start: index * sizeRef,
end: index * sizeRef + sizeRef
};
interpolators.push(animatedValue);
});
this.setState({ interpolators });
}
I had the same issue and I solved by simply setting itemHeight as well.. It might also be that the issue comes from you trying to specify the width and height as a relative size to the screen, and it may only take a number..
return (
<Carousel
data={this.state.entries}
renderItem={this._renderItem}
sliderWidth={sliderWidth}
itemWidth={sliderWidth}
itemHeight={itemHeight}
/>
);
const sliderWidth = Dimensions.get('window').width;
const itemHeight = Dimensions.get('window').height;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With