react-nativereact-native-snap-carousel

React native setState() not re-render as expected


I made a carousel with react-native-snap-carousel and below are the code for carousel. In carousel there're picker and textInput and etc. For render function:

<Carousel
            ref={(c) => { this._carousel = c; }}
            data={this.state.question}
            renderItem={this._renderItem}
            sliderWidth={standard * 1.1}
            itemWidth={standard * 0.9}

            inactiveSlideScale={0.9}
            inactiveSlideOpacity={0.7}

            firstItem={0}

            activeSlideAlignment={'center'}
            containerCustomStyle={styles.slider}
            contentContainerCustomStyle={styles.sliderContentContainer}
              />

For detail rendering:

_renderItem ({item, index}) {
  var content;
  switch (item.id) {
      case 1:
          content = <View style={styles.carousel_cell}>
                        <Text style={styles.carouselItemTitle}>{item.displayLabel}</Text>
                        <TextInput style={styles.editor} onChangeText={(text) => this.setState({comment: text})} value={this.state.comment} />
                    </View>;
          break;
      case 2:
          content = <View style={styles.carousel_cell}>
                        <Text style={styles.carouselItemTitle}>{item.displayLabel}</Text>
                        <Picker mode="dropdown"
                        style={styles.picker}
                        selectedValue={this.state.priority}
                        onValueChange={(itemValue) => this.onPriorityChange(itemValue)}>

                          {this.state.list}
                        </Picker>

                    </View>;
          break;
      default:
          content = <View style={styles.carousel_cell}>
                        <Text style={styles.carouselItemTitle}>{item.displayLabel}</Text>
                        <Text>Unknown</Text>
                    </View>;
          break;

  }

  return content;

}

For event triggering:

onPriorityChange(value) {
    this.setState({priority: value});
}

The problem here is that after I select any item in Picker the state did get updated but on the interface it's not. The render function of Picker will be invoked once I trigger the onChangeText event. At that time the display in Picker will be update as well. However, according to the life cycle, shouldn't the carousel(including its cells) be updated/re-rendered when I setState?

The Stopwatch(from react-native-stopwatch-timer) in carousel will have the same problem.


Solution

  • I don't know this package but the Carousel component seems to inherit from FlatList component.

    The documentation says:

    By passing extraData={this.state} to FlatList we make sure FlatList itself will re-render when the state.selected changes. Without setting this prop, FlatList would not know it needs to re-render any items because it is also a PureComponent and the prop comparison will not show any changes.

    So, try to add extraData={this.state} to your Carousel component.