簡體   English   中英

React Native,如何在ScrollView中只調用一次onScroll事件?

[英]React Native, how to call onScroll event only once inside ScrollView?

我正在使用 React-Native 創建簡單的應用程序,我對ScrollView有問題,我的目標是在滾動結束時發送Ajax請求,它應該只發生一次,而不是每次滾動結束時,重要的是我應該只使用ScrollView ,我我正在使用onScroll事件來測量和檢測滾動 position。

我嘗試了什么:

import * as React from 'react';
import { Text, View, StyleSheet, ScrollView } from 'react-native';
import Constants from 'expo-constants';

// You can import from local files
import AssetExample from './components/AssetExample';

// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';

export default function App() {
  const isCloseToBottom = ({
    layoutMeasurement,
    contentOffset,
    contentSize,
  }) => {
    const paddingToBottom = 20;
    return (
      layoutMeasurement.height + contentOffset.y >=
      contentSize.height - paddingToBottom
    );
  };
  return (
    <ScrollView
      style={{ height: 400 }}
      showsVerticalScrollIndicator={false}
      onScroll={({ nativeEvent }) => {
        if (isCloseToBottom(nativeEvent)) {
          console.log('Call some async function only once when scroll ends');
        }
      }}
      scrollEventThrottle={2}>
      <View>
        <View style={{ height: 400 }}>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
        </View>
      </View>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  paragraph: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
});

小吃演示

您可以使用帶有useRef鈎子和boolean值的ref集。 我稱它為firstTimeRef ,如下所示:

import * as React from 'react';
import { Text, View, StyleSheet, ScrollView } from 'react-native';
import Constants from 'expo-constants';

// You can import from local files
import AssetExample from './components/AssetExample';

// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';

export default function App() {
  const firstTimeRef = React.useRef(true);
  const isCloseToBottom = ({
    layoutMeasurement,
    contentOffset,
    contentSize,
  }) => {
    const paddingToBottom = 20;
    return (
      layoutMeasurement.height + contentOffset.y >=
      contentSize.height - paddingToBottom
    );
  };
  return (
    <ScrollView
      style={{ height: 400 }}
      showsVerticalScrollIndicator={false}
      onScroll={({ nativeEvent }) => {
        if (isCloseToBottom(nativeEvent) && firstTimeRef.current) {
          firstTimeRef.current=false;
          console.log('Call some async function only once when scroll ends');
        }
      }}
      scrollEventThrottle={2}>
      <View>
        <View style={{ height: 400 }}>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
          <View
            style={{ padding: 20, marginVertical: 30, backgroundColor: 'red' }}>
            <Text>SECTION TEXT</Text>
          </View>
        </View>
      </View>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  paragraph: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM