React Native Snap Carousel:不变违规:inputRange 必须单调递增 NaN,NaN,NaN

Ran*_*ynh 6 react-native

我对 React Native 很陌生,我正在尝试使用这个组件:https : //github.com/archriss/react-native-snap-carousel

我尝试使用他们在使用部分提供的代码来创建最简单的工作版本:

    return (
        <Carousel
          ref={(c) => { this._carousel = c; }}
          data={this.state.entries} // this seems to be the problem
          renderItem={this._renderItem}
          sliderWidth='100%'
          itemWidth='80%'
        />
    );
Run Code Online (Sandbox Code Playgroud)

其中“条目”是一个数组。这会导致以下错误:

Invariant Violation: inputRange must be monotonically increasing NaN,NaN,NaN
Run Code Online (Sandbox Code Playgroud)

编辑:这是 _renderItem 方法

_renderItem ({item, index}) {
    return (
        <View style={styles.slide}>
            <Text style={styles.title}>{ item.title }</Text>
        </View>
    );
  }
Run Code Online (Sandbox Code Playgroud)

bla*_*laz 7

如果您进一步深入研究react-native源代码,您可以在文件中找到错误源AnimatedInterpolation.js,其中它期望插值的inputRange是数字数组。所以我最好的猜测是react-native-snap-carousel使用itemWidth值来计算插值数据并将其传递给react-native的动画组件。您可以在此处找到该实现。如果您向 提供非整数值itemWidth,则计算将始终返回 NaN,从而产生该错误。

简短回答:替换itemWidth为实际数字。

2020年1月16日更新:新版本的react-native更改了消息,因此我相应地更新了链接并添加了原始代码:

内部处理程序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,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在react-native-snap-carousel (v3.8.4) 中使用sliderWidth并传递函数inputRange

_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 });
    }
Run Code Online (Sandbox Code Playgroud)


小智 5

我有同样的问题,我也通过简单地设置 itemHeight 解决了..也可能是问题来自您试图将宽度和高度指定为屏幕的相对大小,并且它可能只需要一个数字..

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;
Run Code Online (Sandbox Code Playgroud)