Мой плоский список не рендерится без удаленного отладчика - PullRequest
0 голосов
/ 24 июня 2019

Я работаю над приложением по реакции native.i, у меня проблема. когда мое приложение имеет режим отладки, работает очень хорошо. но в режиме без отладки мой Flatlist не отображает все элементы. Я использую Redux и Sagag Saga

class ComponentGroups extends React.Component {
  constructor (props){
    super(props)
    this.state = {
      listBanner: this.props.item.listBanner
    }
  }
  eventOnscroll = () => {
    console.log('load list banner pls what wrong with u')
  }
  checkRenderView = () => {
    if(this.state.listBanner.length && this.state.listBanner.length === 1) {
      return (
        <ComponentBanner item={this.state.listBanner[0]} typeTab={1}/>
      )
    }
    const dimensions = Dimensions.get('window');
    const screenWidth = dimensions.width;
    return (
      <ScrollView onScroll={this.eventOnscroll}>
      <FlatList
        style={{
          flex: 1,
          width: screenWidth
        }}
        showsHorizontalScrollIndicator={false}
        horizontal={true}
        data={this.state.listBanner}
        removeClippedSubviews={false}
        keyExtractor={(item, index) => index.toString()}
        renderItem={({item, index}) => <ComponentBanner item={item} index={index} typeTab={1}/>}
      />
      </ScrollView>
    )
  }
  render () {
    return (
      <View style={styles.bannerItem}>
        {this.state.listBanner.length && this.checkRenderView()}
      </View>
    )
  }
}

и мой компонент:

class ComponentBanner extends React.Component {
  constructor (props) {
    super(props)
  }
  handlePressDetailBanner = () => {
    detailImageScreen({item: this.props.item, typeTab: 1})
  }
  showViewNewsViewed = () => {
    if(this.props.item.hot && this.props.item.watched) {
      return (
        <View style={styles.viewsLiked}>
          <View style={styles.iconLike}>
            <Text style={styles.news}>Mới</Text>
          </View>
          <View style={styles.iconView}>
            <Text style={styles.viewed}>Đã xem</Text>
          </View>
        </View>
      )
    }
    if(this.props.item.hot && !this.props.item.watched) {
      return (
        <View style={styles.viewsLiked}>
          <View style={styles.iconLike}>
            <Text style={styles.news}>Mới</Text>
          </View>
        </View>
      )
    }
    if(!this.props.item.hot && this.props.item.watched) {
      return (
        <View style={styles.viewsLiked}>
          <View style={styles.iconView}>
            <Text style={styles.viewed}>Đã xem</Text>
          </View>
        </View>
      )
    }
  }
  render () {
    return (
      <View style={styles.bannerItem}>
        <TouchableOpacity onPress ={this.handlePressDetailBanner}>
          <Image source={{uri: this.props.item.url}} style={styles.imageItem} borderRadius={5} resizeMode='stretch'/>
        </TouchableOpacity>
        <View style={styles.titleLikes}>
          {this.showViewNewsViewed()}
          <Text numberOfLines={2} ellipsizeMode='tail' style={styles.textTitle}>{this.props.item.name}</Text>
          <View style={styles.viewsLiked}>
            <View style={styles.iconLike}>
              <Icon
                name='thumb-up'
                color={this.props.item.userLike? Colors.mpAdvertise : Colors.cloud}
                size={Fonts.size.regular}
              />
              <Text style={styles.accountLike}>{this.props.item.totalLike}</Text>
            </View>
            <View style={styles.iconView}>
              <Icon
                name='eye'
                color={Colors.cloud}
                size={Fonts.size.regular}
              />
              <Text style={styles.accountLike}>{this.props.item.totalView}</Text>
            </View>
          </View>
        </View>
      </View>
    )
  }
}
export default ComponentBanner

и визуализация элемента:

render () {
    return (
      <TouchableOpacity onPress ={this.handlePressDetailBanner} style={styles.detailImage}>
        <View style={styles.bannerItem}>
          <View>
            <Image source={{uri: this.props.item.url ? this.props.item.url : ''}} style={styles.imageItem} borderRadius={5} resizeMode='stretch'/>
          </View>
          <View style={styles.titleLikes}>
            <Text numberOfLines={2} ellipsizeMode='tail' style={styles.textTitle}>{this.props.item.name ? this.props.item.name : ''}</Text>
            <View style={styles.viewsLiked}>
              <View style={styles.iconLike}>
                <Icon
                  name='thumb-up'
                  color={this.props.item.userLike? Colors.mpAdvertise : Colors.cloud}
                  size={Fonts.size.regular}
                />
                <Text style={styles.accountLike}>{this.props.item.totalLike ? this.props.item.totalLike : ''}</Text>
              </View>
              <View style={styles.iconView}>
                <Icon
                  name='eye'
                  color={Colors.cloud}
                  size={Fonts.size.regular}
                />
                <Text style={styles.accountLike}>{this.props.item.totalView ? this.props.item.totalView : ''}</Text>
              </View>
            </View>
          </View>
        </View>
      </TouchableOpacity>
    )
  }
}

ОБНОВЛЕНИЕ: извините за забытый рендеринг основного экрана. Группы компонентов:

constructor (props) {
    super(props)
    this.state = {
      params: {
        SourceType: '',
        GroupCode: '',
        NumOfRec: 10,
        PageNum: 1,
        TypeId: '',
      },
      data:[],
      groupBanner:  '',
      groupVideo:  '',
      mainBanner:  '',
      listBanners: [],
      listVideos: [],
      isSelected: 1,
      fetching: false,
      onEndReachedCalledDuringMomentum: true
    }
    Navigation.events().bindComponent(this)
    this.props.getData()
  }
  static getDerivedStateFromProps(nextProps, prevState){
    if (nextProps.fetching !== prevState.fetching){
      return {
        fetching: nextProps.fetching,
        data: nextProps.data,
        listBanners: nextProps.listBanners,
        listVideos: nextProps.listVideos
      }
    }
    else return null;
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevState.fetching !== this.state.fetching) {
    }
  }

  componentDidAppear () {
    Navigation.mergeOptions(this.props.componentId, {
      sideMenu: {
        left: {
          enabled: true
        }
      }
    })
  }

  showSideMenu () {
    Navigation.mergeOptions(this.props.componentId, {
      sideMenu: {
        left: {
          visible: true
        }
      }
    })
  }
  navigationButtonPressed ({ buttonId }) {
    this.showSideMenu()
  }
  handlePressScroll = () => {
    const {params} = this.state
    if(!this.state.fetching) {
      this.setState({
        params: {
          ...params,
          PageNum: params.PageNum + 1,
        }
      }, () => {
        const data = Object.keys(this.state.params).map(key => key + '=' + this.state.params[key]).join('&')
        console.log(data)
        if(this.state.isSelected === 2) {
          this.props.getDataBanner(data)
        }
        if(this.state.isSelected === 3) {
          this.props.getDataVideo(data)
        }
      })
    } else {
      return null
    }
  }
  handlePressSwitchTab = (value) => {
    this.setState({
      isSelected: value,
      params: {
        SourceType: 1,
        GroupCode: '',
        NumOfRec: 10,
        PageNum: 1,
        TypeId: 0
      },
      listBanners: [],
      listVideos: [],
    },()=>{
      if(value === 1) {
        this.props.resetStateHome()
        this.props.getData()
      }
      if(value === 2) {
         this.props.resetStateHome()
        const data = Object.keys(this.state.params).map(key => key + '=' + this.state.params[key]).join('&')
        this.props.getDataBanner(data)
      }
      if(value === 3) {
        this.props.resetStateHome()
        const data = Object.keys(this.state.params).map(key => key + '=' + this.state.params[key]).join('&')
        this.props.getDataVideo(data)
      }
    })
  }
  formatData = (data, numColumns) => {
    const numberOfFullRows = Math.floor(data.length / numColumns)
    let numberOfElementsLastRow = data.length - (numberOfFullRows * numColumns)
    while (numberOfElementsLastRow !== numColumns && numberOfElementsLastRow !== 0) {
      data.push({ key: `blank-${numberOfElementsLastRow}`, empty: true })
      numberOfElementsLastRow++
    }
    return data
  }
  handlePressBanner = () => {
    detailImageScreen({item: this.state.data.mainBanner})
  }
  eventScroll = () => {
    console.log(45544)
  }

  renderViewByState = () => {
    const numColumns = 2;
    if(this.state.data && this.state.data.mainBanner && this.state.data.mainBanner.url) {
      var url = this.state.data.mainBanner.url
    }
    if (this.state.isSelected === 1) {
      if(this.state.fetching) {
        return (
          <View style={styles.styleLoadMore}>
            <BallIndicator color={Colors.mpAdvertise} animationDuration={800} />
          </View>
        )
      } else {
        return (
          <ScrollView onScroll={this.eventScroll} >
            <View style={styles.centered}>
              <TouchableOpacity onPress={this.handlePressBanner} style={styles.mainBannerImage}>
                <Image source={{uri: url}} style={styles.logo} borderRadius={5} resizeMode='stretch'/>
              </TouchableOpacity>
            </View>
            <View style={styles.containerContent}>
              <View style={styles.sectionBanner} >
                <View>
                  <Text style={styles.textBanner}>BANNERS</Text>
                </View>
                <View style={styles.listBanner}>
                  <FlatList
                    data={this.state.data.groupBanner}
                    keyExtractor={(item, index) => index.toString()}
                    renderItem={({item, index}) => <ComponentGroups item={item} index={index} />}
                  />
                </View>
              </View>
              <View style={styles.sectionBanner} >
                <View>
                  <Text style={styles.textBanner}>VIDEOS</Text>
                </View>
                <View style={styles.listBanner}>
                  <ScrollView>
                  <FlatList
                    data={this.state.data.groupVideo}
                    keyExtractor={(item, index) => index.toString()}
                    renderItem={({item, index}) => <ComponentGroupsVideo item={item} index={index} />}
                  />
                  </ScrollView>
                </View>
              </View>
            </View>
          </ScrollView>
        )
      }
    }
    if (this.state.isSelected === 2) {
      if(this.state.fetching && this.state.params.PageNum < 2) {
        return (
          <View style={styles.styleLoadMore}>
            <BallIndicator color={Colors.mpAdvertise} animationDuration={800} />
          </View>
        )
      }
      return (
        <ScrollView onScroll={this.eventScroll}>
        <View style={styles.listBanner}>
          <FlatList
            extraData={this.state}
            ListFooterComponent = {this.renderFooter}
            data={this.state.listBanners}
            keyExtractor={(item, index) => index.toString()}
            renderItem={({item, index}) => <BannerItem item={item} index={index}/>}
            numColumns={countNumber}
            onEndReached={this.handlePressScroll}
            onEndReachedThreshold={0.05}
          />
        </View>
        </ScrollView>
      )
    }
    if (this.state.isSelected === 3) {
      if(this.state.fetching && this.state.params.PageNum < 2) {
        return (
          <View style={styles.styleLoadMore}>
            <BallIndicator color={Colors.mpAdvertise} animationDuration={800} />
          </View>
        )
      }
      return (
        <View style={styles.listBanner}>
          <FlatList
            extraData={this.state}
            data={this.state.listVideos}
            ListFooterComponent = {this.renderFooter}
            keyExtractor={(item, index) => index.toString()}
            renderItem={({item, index}) => <VideosItem item={item} index={index} typeTab={3}/>}
            numColumns={countNumber}
            onEndReached={this.handlePressScroll}
            onEndReachedThreshold={0.01}
          />
        </View>
      )
    }
  }
  renderFooter = () => {
    if(this.state.fetching && this.props.isStopScroll && this.state.params.PageNum > 1) {
      return (
        <View style={styles.styleLoadMoreFooter}>
          <BallIndicator color={Colors.mpAdvertise} animationDuration={800} />
        </View>
      )
    }
    return null
  }
  render () {
    return (
      <View style={styles.mainContainer} testID='launchScreen'>
        <View style={styles.tabBarHome}>
          <View style={[styles.itemTab, this.state.isSelected === 1 ? styles.itemTabActive : null]}>
            <TouchableOpacity testID='loginScreenLoginButton' style={styles.loginButtonWrapper} onPress={() => this.handlePressSwitchTab(1)}>
              <View style={styles.loginButton}>
                <Text style={[styles.itemText, this.state.isSelected === 1 ? styles.itemTextActive : null]}>Nổi bật</Text>
              </View>
            </TouchableOpacity>
          </View>
          <View style={[styles.itemTab,  this.state.isSelected === 2 ? styles.itemTabActive : null]}>
            <TouchableOpacity testID='loginScreenLoginButton' style={styles.loginButtonWrapper} onPress={() => this.handlePressSwitchTab(2)}>
              <View style={styles.loginButton}>
                <Text style={[styles.itemText, this.state.isSelected === 2 ? styles.itemTextActive : null]}>Banner</Text>
              </View>
            </TouchableOpacity>
          </View>
          <View style={[styles.itemTab,  this.state.isSelected === 3 ? styles.itemTabActive : null]}>
            <TouchableOpacity testID='loginScreenLoginButton' style={styles.loginButtonWrapper} onPress={() => this.handlePressSwitchTab(3)}>
              <View style={styles.loginButton}>
                <Text style={[styles.itemText, this.state.isSelected === 3 ? styles.itemTextActive : null]}>Videos</Text>
              </View>
            </TouchableOpacity>
          </View>
        </View>
        {this.renderViewByState()}
      </View>
    )
  }
}
const mapStateToProps = (state) => {
  return {
    data: state.home.data,
    listBanners: state.home.listBanners,
    listVideos: state.home.listVideos,
    fetching: state.home.fetching,
    cart: state.login.dataCart,
    isStopScroll: state.home.isStopScroll
  }
}
const mapDispatchToProps = (dispatch) => {
  return {
    getData: () => dispatch(HomeActions.homeRequest()),
    getDataBanner: (data) => dispatch(HomeActions.bannerRequest(data)),
    getDataVideo: (data) => dispatch(HomeActions.videoRequest(data)),
    resetStateHome: () => dispatch(HomeActions.resetStateHome())
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(HomeScreen)

Приведенный выше код отрисовывает мой элемент в плоском списке. В режиме отладки работает очень хорошо, но в режиме релиза он вообще не отображается

1 Ответ

0 голосов
/ 24 июня 2019

пожалуйста, попробуйте это

<FlatList
        style={{
          flex: 1,
          width: screenWidth
        }}
        extraData={this.state}    //<--- add this line
        showsHorizontalScrollIndicator={false}
        horizontal={true}
        data={this.state.listBanner}
        removeClippedSubviews={false}
        keyExtractor={(item, index) => index.toString()}
        renderItem={({item, index}) => <ComponentBanner item={item} index={index} typeTab={1}/>}
      />
...