如何在FlatList中使用callBack()挂钩?

问题描述 投票:0回答:1

我正在尝试改善应用程序的性能,因此我使用FC渲染项目,

但是对我来说效果不佳!

当我向下滚动到++页面时>

并且在useEffect()中,我发送了一个请求,以根据页面的工作获取新数据,并在UI中很好地呈现项目! “加载更多功能”。

但是当我在单击项目之前记录“歌曲”整个数组时,我只得到前两页!有时我得到一个空数组。

那么,我的代码在这里出什么问题了?

const LastSongs = (props) => {
  const [songs, setSongs] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [page, setPage] = React.useState(1);
  const [last_page, setLast_page] = React.useState(1);

  const {saveSongs, isPlaying, isPauseTrigger} = props;

  const _renderItems = useCallback(
    // the same reference with each rerender
    ({item, index}) => (
      <TouchableNativeFeed
        key={item.id}
        onPress={() => {
          console.log('onPress', songs);
          saveSongs(songs, index);
          isPlaying(true);
          isPauseTrigger(!isPauseTrigger);
        }}
        background={TouchableNativeFeedback.Ripple('white')}
        delayPressIn={0}
        useForeground>
        <Card
          style={{
            justifyContent: 'center',
            alignItems: 'center',
            backgroundColor: '#121212',
            flex: 1,
          }}>
          <FastImage
            source={{uri: item.img}}
            resizeMode={FastImage.resizeMode.cover}
            style={styles.cardImg}
          />
          <Body style={{...styles.cardItem, width: '100%'}}>
            <View style={styles.radioCardName}>
              <Text style={styles.text} numberOfLines={1}>
                {item.name}
              </Text>
            </View>
          </Body>
        </Card>
      </TouchableNativeFeed>
    ),
    [saveSongs, isPlaying, isPauseTrigger],
  );

  const renderFooter = useCallback(
    // the same reference with each rerender
    () => {
      return loading ? (
        <View style={styles.loader}>
          <ActivityIndicator size="large" />
        </View>
      ) : null;
    },
    [loading],
  );

  const handleLoadMore = useCallback(
    // the same reference with each rerender
    () => {
      if (page <= last_page - 1) {
        setPage(page + 1);
      }
    },
    [page, last_page],
  );

  React.useEffect(() => {
    let isCancelled = false;
    setLoading(true);

    const getData = async () => {
      let response = await API.get(`/tracks?page=${page}`);
      let lastPage = response.data.data.items.last_page;
      setLast_page(lastPage);
      let {
        data: {
          data: {
            items: {data},
          },
        },
      } = response;
      let All_Songs = [];
      data.map((track) =>
        All_Songs.push({
          id: track.id,
          name: track.name,
          url: URL + track.sounds,
          img: URL + track.avatar,
        }),
      );
      setSongs(songs.concat(All_Songs));
      setLoading(false);
    };
    getData();
    console.log('songs', songs);
  }, [page]);

  return (
    <Container style={styles.container}>
      <Header
        style={styles.darkHeader}
        androidStatusBarColor="#121212"
        iosBarStyle="light-content">
        <Left>
          <Button transparent onPress={() => props.navigation.goBack()}>
            <Icon name="ios-arrow-forward" style={styles.colorWhite} />
          </Button>
        </Left>
        <Body>
          <Title style={styles.headerText}>last songs</Title>
        </Body>
        <Right></Right>
      </Header>
      <FlatList
        data={songs}
        keyExtractor={_keyExtractor} // the same reference with each rerender
        initialNumToRender={10}
        contentContainerStyle={styles.contentContainerStyle} // the same reference with each rerender
        columnWrapperStyle={styles.columnWrapperStyle} // the same reference with each rerender
        numColumns={2}
        ListEmptyComponent={_renderListEmptyComponent} // the same reference with each rerender
        renderItem={_renderItems}
        onEndReached={handleLoadMore}
        onEndReachedThreshold={100}
        ListFooterComponent={renderFooter}
        removeClippedSubviews={true}
        maxToRenderPerBatch={1} // Reduce number in each render batch
        maxToRenderPerBatch={100} // Increase time between renders
        windowSize={7}
      />
    </Container>
  );
};

const _keyExtractor = (song) => song.id;

const _renderListEmptyComponent = () => <EmptyList />;

const mapDispatchToProps = (dispatch) => {
  return {
    isPlaying: (_isPlaying) => {
      dispatch(isPlayingAction(_isPlaying));
    },

    isPauseTrigger: (_isPause) => {
      dispatch(isPauseAction(_isPause));
    },

    saveSongs: (songs, index) => {
      dispatch(saveSongsPlayer(songs, index));
    },
  };
};

export default connect(null, mapDispatchToProps)(LastSongs);

我正在尝试改善应用程序的性能,因此我使用FC渲染项目,但对我来说效果不佳!当我向下滚动到++ page并使用useEffect()时,我发送请求以获取新数据...

javascript reactjs react-native react-hooks
1个回答
0
投票

尝试更改_renderItems上的依赖项数组以包括歌曲。更改为:[saveSongs, isPlaying, isPauseTrigger, songs]。这样,callBack上的关闭将始终包含最新歌曲。

© www.soinside.com 2019 - 2024. All rights reserved.