react-native-swiper active dot无法更新解决方案

问题描述

一个轮播图组件,展示网络图片,为了避免闪屏,先用本地默认图片作为占位符。

{previewUrl.length > 0 ? (
  <Swiper loop={true} height={windowWidth}>
    {previewUrl.map((item, index) => (
      <Image
        key={index}
        style={DetailStyle.image}
        resizeMode="contain"
        source={
  
  {uri: item}}
      />
    ))}
  </Swiper>
) : (
  <Swiper loop={true} height={windowWidth}>
    <Image
      style={DetailStyle.image}
      resizeMode="contain"
      source={require("@/static/defaultAvator.jpeg")}
    />
  </Swiper>
)}

结论

占位符必须在2张以上,不然react-native-swipper会认为当前激活的index一直为0。

{previewUrl.length > 0 ? (
  <Swiper loop={true} height={windowWidth}>
    {previewUrl.map((item, index) => (
      <Image
        key={index}
        style={DetailStyle.image}
        resizeMode="contain"
        source={
  
  {uri: item}}
      />
    ))}
  </Swiper>
) : (
  <Swiper loop={true} height={windowWidth}>
    <Image
      style={DetailStyle.image}
      resizeMode="contain"
      source={require("@/static/defaultAvator.jpeg")}
    />
    <Image
      style={DetailStyle.image}
      resizeMode="contain"
      source={require("@/static/defaultAvator.jpeg")}
    />
  </Swiper>
)}

image外层也不能包裹fragment,不然react-native-swipper仍然会认为只有一个子节点。

分析过程

布局结束后触发onLayout,如果子节点数大于1就会更新this.internals.offset[this.state.dir]。

  onLayout = event => {
    const { width, height } = event.nativeEvent.layout
    const offset = (this.internals.offset = {})
    const state = { width, height }

    if (this.state.total > 1) {
      let setup = this.state.index
      if (this.props.loop) {
        setup++
      }
      offset[this.state.dir] =
        this.state.dir === 'y' ? height * setup : width * setup
    }
    // ...
  }

滑动结束会调用updateIndex,根据diff判断是否需要更新子节点。

  updateIndex = (offset, dir, cb) => {
    const state = this.state
    let index = state.index
    if (!this.internals.offset)
      this.internals.offset = {}
    // 如果子节点数<2,this.internals.offset[dir]会是undefined,diff为NaN
    const diff = offset[dir] - this.internals.offset[dir]
    const step = dir === 'x' ? state.width : state.height
    let loopJump = false

    // diff为NaN这里就会返回,导致index和this.internals.offset均无法正常更新
    if (!diff) return

    // ...

    const newState = {}
    newState.index = index
    newState.loopJump = loopJump

    this.internals.offset = offset

    // ...
    this.setState(newState, cb)
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值