【问题标题】:Implement pull to refresh FlatList实现拉取刷新 FlatList
【发布时间】:2018-05-14 05:41:38
【问题描述】:

请帮助我在我的应用程序上实现拉动刷新,我对本机反应有点新,谢谢。我不知道如何处理onRefresh和刷新。

class HomeScreen extends Component {
  state = { refreshing: false }

  _renderItem = ({ item }) => <ImageGrid item={item} />

  _handleRefresh = () => {

  };

  render() {
    const { data } = this.props;
    if (data.loading) {
      return (
        <Root>
          <Loading size="large" />
        </Root>
      )
    }
 return (
   <Root>
     <HomeHeader />
     <FlatList
       contentContainerStyle={{ alignSelf: 'stretch' }}
       data={data.getPosts}
       keyExtractor={item => item._id}
       renderItem={this._renderItem}
       numColumns={3}
       refreshing={this.state.refreshing}
       onRefresh={this._handleRefresh}
     />
   </Root>
  );
 }
}

export default graphql(GET_POSTS_QUERY)(HomeScreen);

【问题讨论】:

    标签: javascript react-native expo


    【解决方案1】:

    “拉动刷新”概念意味着列表可以手动刷新,因此可以在当前视图之外更改(例如从服务器获取)。所以回调onRefresh 必须触发数据重新加载过程(例如向服务器发送请求)并将refreshing 变量设置为真值。这将通过显示加载指示器通知用户该过程已启动。准备好数据后,您需要将 refreshing 设置为 falsy,以便视图隐藏加载指示器。

    【讨论】:

      【解决方案2】:

      这是我能做的最好的了。 my Code Image

      当我将其拉下时,它不会从服务器重新获取数据我正在运行通过 Apollo 连接到应用程序的 graphql 服务器,并且我不知道如何在 _getData() 函数中从服务器获取数据。

      【讨论】:

      • 把代码sn-p贴在这里会很有帮助。
      【解决方案3】:

      您还可以在FlatlistScrollView 和任何其他列表组件中使用refreshControl

      <FlatList
        contentContainerStyle={{ alignSelf: 'stretch' }}
        data={data.getPosts}
        keyExtractor={(item) => item._id}
        renderItem={this._renderItem}
        numColumns={3}
        refreshControl={
          <RefreshControl
            refreshing={this.state.refreshing}
            onRefresh={this._handleRefresh}
          />
        }
      />
          
      

      【讨论】:

      • 如果你设置了 prop onRefresh,FlatList 会自动设置RefreshControl,虽然它是一个默认值。
      【解决方案4】:

      设置变量

      this.state = { 
          isFetching: false,
      }
      

      创建刷新函数

      onRefresh() {
          this.setState({isFetching: true,},() => {this.getApiData();});
      }
      

      最后设置onRefresh并在FlatList中刷新。

      <FlatList
          data={ this.state.FlatListItems }
          onRefresh={() => this.onRefresh()}
          refreshing={this.state.isFetching}
      />
      

      在getApiData函数中获取数据后确保设置false isFetching。

      this.setState({ isFetching: false })
      

      【讨论】:

      • 嘿@Krish 我这样做了,但数据中的最后一项它不能消失,当我拉动刷新“加载”时卡住并且无法获取新数据!
      • @DevAS 在调用 reload 函数之前清空数组(当你设置空白数组 flatlist 必须重新加载)并检查你的 FlatList 是否仍然显示最后一项。
      • 我不明白你的意思:/你说调用 onRefresh 时清空数组?
      • @DevAS 我的意思是清空数组(在我的示例中为“FlatListItems”),它必须刷新 Flatlist 并且不应该显示最后一项。请分享代码,以便我查看。
      【解决方案5】:

      // 表示平面列表中拉动刷新的示例代码。相应地修改。

      import React, { Component } from 'react'
          import { Text, View,StyleSheet,FlatList,Dimensions,Image,TouchableHighlight } from 'react-native'
      
          export default class Home extends Component {
      
              constructor(props) 
              {
                  super(props);
              this.state = {
                  data : [],
                  gender : "",
                  isFetching: false,
              }
              }
      
          componentWillMount()
          {
      
              this.searchRandomUser()
          }
      
          onRefresh() {
              this.setState({ isFetching: true }, function() { this.searchRandomUser() });
           }
      
          searchRandomUser = async () =>
          {
             const RandomAPI = await fetch('https://randomuser.me/api/?results=20')
             const APIValue = await RandomAPI.json();
              const APIResults = APIValue.results
                console.log(APIResults[0].email);
                this.setState({
                    data:APIResults,
                    isFetching: false
                })
      
          }
      
            render() {
              return (
                <View style = {styles.container}>
           <TouchableHighlight
           onPressOut = {this.searchRandomUser}
               style = {{width:deviceWidth - 32, height:45,backgroundColor: 'green',justifyContent:"center",alignContent:"center"}}>
                    <Text style = {{fontSize:22,color: 'white',fontWeight: 'bold',textAlign:"center"}}>Reload Data</Text>
               </TouchableHighlight>
           <FlatList
                  data={this.state.data}
                  onRefresh={() => this.onRefresh()}
                refreshing={this.state.isFetching}
                  keyExtractor = { (item, index) => index.toString() }
                  renderItem={({item}) =>
                  <View style = {styles.ContainerView}>
                  <View>
          <Image
          source={{uri : item.picture.large}}
          style = {{height:100,width:100,borderRadius: 50,marginLeft: 4}}
          resizeMode='contain'
          />
          </View>
      
          <View style = {{flexDirection: 'column',marginLeft:16,marginRight: 16,flexWrap:'wrap',alignSelf:"center",width: deviceWidth-160}}>
          <Text>Email Id : {item.email}</Text>
      
          <Text>Full Name : {this.state.gender} {item.name.first} {item.name.last}</Text>
          <Text>Date of birth : {item.dob.age}</Text>
          <Text>Phone number : {item.phone}</Text>
      
          </View>
      
          </View>
                  }
                  />
                </View>
              )
            }
          }
          const deviceWidth = Dimensions.get('window').width
          const deviceHeight = Dimensions.get('window').height
          const styles = StyleSheet.create({
              container: {
                flex: 1,
                alignItems: 'center',
                justifyContent: 'center',
                marginTop:22
              },
              ContainerView:
              {
                  // backgroundColor:'grey',
                  marginBottom:20,
                  paddingVertical:10,
                  backgroundColor: '#F5F5F5',
      
                  borderBottomWidth:0.5,
                  borderBottomColor:'grey',
                  width: deviceWidth-40,
                  marginLeft:20,
                  marginRight:20,
                  marginTop:20,
                  flexDirection:'row'
              }
            });
      

      【讨论】:

      【解决方案6】:

      不要在平面列表上使用 pull 来刷新,而是在 Scroll View 上使用。

      设置刷新状态

      this.state = { 
           isFetching: false,
        }
      

      在ScrollView中设置onFresh

      <ScrollView
        refreshControl={
          <RefreshControl
            refreshing={this.state.refresh}
            onRefresh={() => this.onRefresh()}
            tintColor="red"
          />
        }>
        <FlatList data={data} renderItem={this._renderItem} numColumns={3} />
      </ScrollView>;
      
      

      在 OnRefreshFunction 中

        onRefresh() {
          this.setState({refresh: true});
          setTimeout(() => {
            this.setState({refresh: false});
          }, 2000);
        }
      

      【讨论】:

      • 这个问题是专门针对如何为 FlatList 做的,而不是 FlatList 的替代品是什么。
      【解决方案7】:
      const [refreshing, setRefreshing] = useState(false)
          
       <FlatList
           style={{ padding: 15 }}
           refreshControl={
               <RefreshControl 
                   refreshing={refreshing} 
                   onRefresh={_onRefresh}
                   tintColor="#F8852D"/>
           }
           showsVerticalScrollIndicator={false}
           data={listData}
           renderItem={renderItem}
           item={(item, index) => index.toStirng()}
           onEndReachedThreshold={0.8}
           onEndReached={() => onEndReached()}
           ListFooterComponent={() => renderFooter()}
       /> 
      

      _onRefresh 函数

      const _onRefresh = () => {
          console.log('_onRefresh')
          setRefreshing(true);
          getPosts();
      };
      

      【讨论】:

      • refreshingonRefresh 已经是 FlatList 道具。还需要在里面加上RefreshControl 标签吗?
      • @deepanshu 请把index.toStirng()的拼写更正为index.toString()
      【解决方案8】:

      如果有人有兴趣使用 React Hooks 来做这件事,那就是:

      首先创建isRefreshing状态:

      const [isRefreshing, setIsRefreshing] = useState(false)
      

      然后创建您的onRefresh 函数调用API 来刷新数据:

      const onRefresh = () => {
          //set isRefreshing to true
          setIsRefreshing(true)
          callApiMethod()
          // and set isRefreshing to false at the end of your callApiMethod()
      }
      

      然后,您的 FlatList 组件看起来像这样:

      return (
          <FlatList
              style={styles.flatList}
              onRefresh={onRefresh}
              refreshing={isRefreshing}
              data={data}
              renderItem={renderItem}
              keyExtractor={item => item.id.toString()}
          />
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-25
        • 1970-01-01
        • 2011-09-17
        • 2015-11-28
        • 1970-01-01
        • 2020-01-08
        • 2017-12-31
        • 1970-01-01
        相关资源
        最近更新 更多