为了账号安全,请及时绑定邮箱和手机立即绑定

ListFooterComponent 不能正常工作?

ListFooterComponent 不能正常工作?

繁花不似锦 2022-06-16 17:28:38
我对 Flatlist 有一个奇怪的问题,当我向下滚动时,我从 API 获取了数据,我增加了页面 +1,在页脚中,我渲染了一个微调器,但是当最后一页 == 当前页面时,这意味着除了微调器没有数据来卡在底部,尽管我将其更新为假!那么这里有什么问题!顺便说一句,当我在 FlatList 中以这种方式调用 renderFooterListFooterComponent={()=> this._renderFooter()} // it disappeare the bottom spiner if last page == current page but I have an unexpected re-rendering and app laggay and in some time spinner disappeared even I scrolling to bottom!!代码class LastSongs extends React.PureComponent {  constructor() {    super();    this.state = {      songs: [],      loading: false,      page: 1,      last_page: 1,    };    this.isCancelled = false;  }  manipulateArray = async (array) => {    let songs = [];    array.map((track) =>      songs.push({        id: track.id,        name: track.name,        url: URL + track.sounds,        img: URL + track.avatar,      }),    );    return songs;  };  getData = async () => {    try {      this.setState({loading: true});      let response = await API.get(`/tracks?page=${this.state.page}`);      let lastPage = response.data.data.items.last_page;      let {        data: {          data: {            items: {data},          },        },      } = response;      let All_Songs = await this.manipulateArray(data);      this.setState({        songs: this.state.songs.concat(All_Songs),        last_page: lastPage,      });    } catch (err) {      console.log('err', err);    }  };  _renderItems = ({item, index}) => (    <TouchableNativeFeed      key={item.id}      onPress={() => {        this.props.saveSongs(this.state.songs, index);        this.props.isPlaying(true);        this.props.isPauseTrigger(!this.props.isPauseTrigger);      }}  );
查看完整描述

1 回答

?
慕沐林林

TA贡献2016条经验 获得超9个赞

当您滚动到底部时,您正在调用一个超时的异步函数。该超时将覆盖您的以下代码并将 loading 再次设置为 true。所以在这种情况下加载永远不会是错误的。


 } else if (this.state.page === this.state.last_page) {

      this.setState({loading: false}, () =>

        console.log('if--loading', this.state.loading), // log false!! that's mean a spinner should disapeare

      );

 }

你在这里需要两件事。


1) 尝试在你的 catch 块中将 loading 设置为 false。


} catch (err) {

   console.log('err', err);

   this.setState({loading: false});

}

2) 在您的状态中添加另一个isAllDataFetched初始值为 false 的值。当您从 API 接收到空数据时,将 loading 设置为 false。不确定您的数据如何,但可以执行以下操作;


getData = async () => {

    try {

      this.setState({loading: true});

      let response = await API.get(`/tracks?page=${this.state.page}`);

      let lastPage = response.data.data.items.last_page;

      let {

        data: {

          data: {

            items: {data},

          },

        },

      } = response;


      // if it's an array

      if(data.length === 0) {

         this.setState({loading: false, isAllDataFetched: true});

      }

      //...

    } catch (err) {

      console.log('err', err);

    }

  };

最后,在您的 handleLoadMore 方法中添加以下行。


handleLoadMore = () => {

 if(this.state.isAllDataFetched) return;

我为你创建了一个演示。您可以按照此逻辑使其工作。它与你所拥有的有点不同,但我认为它会有所帮助。


这是代码。


import React from 'react';

import {

  View, Text, FlatList, ActivityIndicator, SafeAreaView

} from 'react-native';



class App extends React.PureComponent {

  state = {

    songs: [

      {

        userId: 1,

        id: 1,

        title: 'delectus aut autem 1',

        completed: false,

      },

      {

        userId: 1,

        id: 2,

        title: 'delectus aut autem 2',

        completed: false,

      },

    ],

    loading: false,

    page: 3,

    totalPage: 10,

  };


  componentDidMount() {

    this.getData();

  }


  getData = async () => {

    const { songs } = this.state;

    try {

      this.setState({ loading: true });

      const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${this.state.page}`, {

        headers: {

          'Content-Type': 'application/json',

        },

      });

      const json = await response.json();


      this.setState({

        songs: [...songs, json],

      });

      this.setState({ loading: false });

    } catch (err) {

      console.log('err', err);

      this.setState({ loading: false });

    }

  };


  renderItems = ({ item }) => (

    <Text style={{ backgroundColor: 'blue', height: 200, marginBottom: 5 }}>{`${item.title}-${item.id}`}</Text>

  );


  onEndReached = () => {

    const { page, loading, totalPage } = this.state;


    if (loading) return;


    if (page <= totalPage) {

      this.setState({ loading: true, page: page + 1 }, () =>

        setTimeout(() => {

          this.getData();

        }, 2000));

    } else {

      this.setState({ loading: false });

    }

  }


  renderFooter = () => {

    const { loading } = this.state;


    if (loading) {

      return (

        <View>

          <ActivityIndicator color="#000" size="large" />

        </View>

      );

    }

    return null;

  }


  renderListEmptyComponent = () => <View />;


  render() {

    const { songs } = this.state;

    return (

      <SafeAreaView style={{ flex: 1, backgroundColor: 'red' }}>

        <FlatList

          data={songs}

          keyExtractor={song => song.id}

          initialNumToRender={10}

          contentContainerStyle={{ flexFrow: 1, backgroundColor: 'white' }}

          style={{ flex: 1 }}

          ListEmptyComponent={this.renderListEmptyComponent}

          renderItem={this.renderItems}

          onEndReached={this.onEndReached}

          onEndReachedThreshold={0.7}

          ListFooterComponent={this.renderFooter}

        />

      </SafeAreaView>

    );

  }

}

export default App;

这里有一个工作演示(使用 iOS 设备)


查看完整回答
反对 回复 2022-06-16
  • 1 回答
  • 0 关注
  • 270 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信