ListFooterComponent 不能正常工作?

我对 Flatlist 有一个奇怪的问题,当我向下滚动时,我从 API 获取了数据,我增加了页面 +1,在页脚中,我渲染了一个微调器,但是当最后一页 == 当前页面时,这意味着除了微调器没有数据来卡在底部,尽管我将其更新为假!那么这里有什么问题!


顺便说一句,当我在 FlatList 中以这种方式调用 renderFooter


ListFooterComponent={()=> 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);

      }}

  );


繁花不似锦
浏览 409回答 1
1回答

慕沐林林

当您滚动到底部时,您正在调用一个超时的异步函数。该超时将覆盖您的以下代码并将 loading 再次设置为 true。所以在这种情况下加载永远不会是错误的。&nbsp;} else if (this.state.page === this.state.last_page) {&nbsp; &nbsp; &nbsp; this.setState({loading: false}, () =>&nbsp; &nbsp; &nbsp; &nbsp; console.log('if--loading', this.state.loading), // log false!! that's mean a spinner should disapeare&nbsp; &nbsp; &nbsp; );&nbsp;}你在这里需要两件事。1) 尝试在你的 catch 块中将 loading 设置为 false。} catch (err) {&nbsp; &nbsp;console.log('err', err);&nbsp; &nbsp;this.setState({loading: false});}2) 在您的状态中添加另一个isAllDataFetched初始值为 false 的值。当您从 API 接收到空数据时,将 loading 设置为 false。不确定您的数据如何,但可以执行以下操作;getData = async () => {&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; this.setState({loading: true});&nbsp; &nbsp; &nbsp; let response = await API.get(`/tracks?page=${this.state.page}`);&nbsp; &nbsp; &nbsp; let lastPage = response.data.data.items.last_page;&nbsp; &nbsp; &nbsp; let {&nbsp; &nbsp; &nbsp; &nbsp; data: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; items: {data},&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; } = response;&nbsp; &nbsp; &nbsp; // if it's an array&nbsp; &nbsp; &nbsp; if(data.length === 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;this.setState({loading: false, isAllDataFetched: true});&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; //...&nbsp; &nbsp; } catch (err) {&nbsp; &nbsp; &nbsp; console.log('err', err);&nbsp; &nbsp; }&nbsp; };最后,在您的 handleLoadMore 方法中添加以下行。handleLoadMore = () => {&nbsp;if(this.state.isAllDataFetched) return;我为你创建了一个演示。您可以按照此逻辑使其工作。它与你所拥有的有点不同,但我认为它会有所帮助。这是代码。import React from 'react';import {&nbsp; View, Text, FlatList, ActivityIndicator, SafeAreaView} from 'react-native';class App extends React.PureComponent {&nbsp; state = {&nbsp; &nbsp; songs: [&nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; userId: 1,&nbsp; &nbsp; &nbsp; &nbsp; id: 1,&nbsp; &nbsp; &nbsp; &nbsp; title: 'delectus aut autem 1',&nbsp; &nbsp; &nbsp; &nbsp; completed: false,&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; userId: 1,&nbsp; &nbsp; &nbsp; &nbsp; id: 2,&nbsp; &nbsp; &nbsp; &nbsp; title: 'delectus aut autem 2',&nbsp; &nbsp; &nbsp; &nbsp; completed: false,&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; ],&nbsp; &nbsp; loading: false,&nbsp; &nbsp; page: 3,&nbsp; &nbsp; totalPage: 10,&nbsp; };&nbsp; componentDidMount() {&nbsp; &nbsp; this.getData();&nbsp; }&nbsp; getData = async () => {&nbsp; &nbsp; const { songs } = this.state;&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; this.setState({ loading: true });&nbsp; &nbsp; &nbsp; const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${this.state.page}`, {&nbsp; &nbsp; &nbsp; &nbsp; headers: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Content-Type': 'application/json',&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; const json = await response.json();&nbsp; &nbsp; &nbsp; this.setState({&nbsp; &nbsp; &nbsp; &nbsp; songs: [...songs, json],&nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; this.setState({ loading: false });&nbsp; &nbsp; } catch (err) {&nbsp; &nbsp; &nbsp; console.log('err', err);&nbsp; &nbsp; &nbsp; this.setState({ loading: false });&nbsp; &nbsp; }&nbsp; };&nbsp; renderItems = ({ item }) => (&nbsp; &nbsp; <Text style={{ backgroundColor: 'blue', height: 200, marginBottom: 5 }}>{`${item.title}-${item.id}`}</Text>&nbsp; );&nbsp; onEndReached = () => {&nbsp; &nbsp; const { page, loading, totalPage } = this.state;&nbsp; &nbsp; if (loading) return;&nbsp; &nbsp; if (page <= totalPage) {&nbsp; &nbsp; &nbsp; this.setState({ loading: true, page: page + 1 }, () =>&nbsp; &nbsp; &nbsp; &nbsp; setTimeout(() => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.getData();&nbsp; &nbsp; &nbsp; &nbsp; }, 2000));&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; this.setState({ loading: false });&nbsp; &nbsp; }&nbsp; }&nbsp; renderFooter = () => {&nbsp; &nbsp; const { loading } = this.state;&nbsp; &nbsp; if (loading) {&nbsp; &nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; &nbsp; <View>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ActivityIndicator color="#000" size="large" />&nbsp; &nbsp; &nbsp; &nbsp; </View>&nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; }&nbsp; &nbsp; return null;&nbsp; }&nbsp; renderListEmptyComponent = () => <View />;&nbsp; render() {&nbsp; &nbsp; const { songs } = this.state;&nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; <SafeAreaView style={{ flex: 1, backgroundColor: 'red' }}>&nbsp; &nbsp; &nbsp; &nbsp; <FlatList&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data={songs}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keyExtractor={song => song.id}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; initialNumToRender={10}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; contentContainerStyle={{ flexFrow: 1, backgroundColor: 'white' }}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; style={{ flex: 1 }}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ListEmptyComponent={this.renderListEmptyComponent}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; renderItem={this.renderItems}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onEndReached={this.onEndReached}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onEndReachedThreshold={0.7}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ListFooterComponent={this.renderFooter}&nbsp; &nbsp; &nbsp; &nbsp; />&nbsp; &nbsp; &nbsp; </SafeAreaView>&nbsp; &nbsp; );&nbsp; }}export default App;这里有一个工作演示(使用 iOS 设备)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript