问题描述
一个轮播图组件,展示网络图片,为了避免闪屏,先用本地默认图片作为占位符。
{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)
}