sdcxtech/react-native-troika

@sdcx/pull-to-refresh 在 ios 上快速下滑会抖动

Opened this issue · 8 comments

85f311cb71ace310ea74c9863f9fbbd4_6238227874822596366.mp4

只有第一次进入后快速下拉会触发这个抖动

在第一次加载完成后,后续如何下拉刷新都不会有问题

快速下拉具体是指什么?下拉时列表正在刷新?还是页面未处于 visible(appear) 状态?

快速下拉就是字面意思,页面已经渲染完成,手势快速下滑会导致,如果手势下滑速度慢则不会导致抖动

机型:模拟器iphone15,真机iphone14(16.7.2)
RN版本:0.70
复现代码:

<PullToRefresh
        style={style}
        header={
          <PullToRefreshHeader refreshing={refreshing} onRefresh={onRefresh}>
            <View style={[styles.headerContainer, headerStyle]}>
              <ShouldRender condition={!headerComponent}>
                <LottieView
                  {...(lottieProps || {})}
                  style={styles.loading}
                  ref={animationRef}
                  source={AnimationSource}
                  autoPlay={false}
                  loop
                />
                <ShouldRender condition={!isNil(text)}>
                  <Text
                    style={styles.text}
                    numberOfLines={2}
                    ellipsizeMode="tail"
                  >
                    {text}
                  </Text>
                </ShouldRender>
              </ShouldRender>
            </View>
          </PullToRefreshHeader>
        }
      >
        {children}
      </PullToRefresh>

再此排查了一次,children 中数据过多时会出现这种情况,如果把data的数据减少到5条则正常,反之不正常

const data: any = [];
for (let i = 0; i < 50; i++) {
  data.push({
    key: `data-${i}`,
    text: `number: ${i}`,
    on: false,
  });
}

const Item = ({title}: {title: string}) => (
  <View style={styles.item}>
    <Text style={styles.title} onPress={console.log}>
      {title} <Text>{Platform.OS}</Text>
    </Text>
  </View>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 10,
    marginHorizontal: 16,
  },
  item: {
    backgroundColor: '#f9c2ff',
    padding: 20,
    marginVertical: 8,
  },
  header: {
    fontSize: 16,
    backgroundColor: '#fff',
  },
  title: {
    fontSize: 16,
  },
});

const PullToRefreshScreen = () => {
  const [loading, setLoading] = useState(false);

  const onRefresh = () => {
    setLoading(true);
    return new Promise(resolve => {
      setTimeout(() => {
        setLoading(false);
        resolve('');
      }, 3000);
    });
  };

  return (
    <View style={{flex: 1}}>
      <PullToRefreshNative
        refreshing={loading}
        onRefresh={onRefresh}
        text="南美、非洲等国家外汇少,本币报价获得更多商机">
        <FlatList
          style={{overflow: 'scroll'}}
          data={data}
          nestedScrollEnabled
          renderItem={(renderItem: any) => {
            const {item} = renderItem;
            return <Item title={item.key} />;
          }}
        />
      </PullToRefreshNative>
    </View>
  );
};

export default PullToRefreshScreen;

你好,我这边无法重现这个问题,是否可以提供一个能重现此问题的 repo 给我,或直接发送到我的邮箱 listenzz@163.com

@Linkontoask , 暂时不明是啥原因,可以使用 @react-navigation/native-stack 替换 @react-navigation/stack 来规避这个问题。

@Linkontoask 应该和 PullToRefresh 无关,单单是一个 FlatList,第一次进入后快速下拉也会触发这个抖动。

@LinkontoaskFlatList 替换为 FlashList 即无此问题。

https://github.com/Shopify/flash-list