簡體   English   中英

React Native 避免 FlatList 在我 select 一項時重新渲染

[英]React Native avoid FlatList re-render when I select one item

描述

我正在實現一個圖像選擇器,但有一些我需要解決的性能問題......在我的組件中,用戶可以從他的畫廊中 select 多個項目(圖像)(FlatList 呈現他的畫廊中的所有圖像)。 當某個項目被選中時,它被添加到所選圖像的數組中(它是一個狀態)。

問題

由於數組是有狀態的,組件將重新渲染......但我只需要重新渲染用戶單擊的圖像(因為其中會顯示一個徽章)而不是完整的 FlatList。

任何想法如何做到這一點?

代碼

const keyExtractor = ({ uri }) => uri;

class ImagePicker extends React.Component {
  static propTypes = {
    ...
  };

  loading = false;
  cursor = null;

  state = {
    images: [],
    pickedImages: [], // <----------------------------------
  };

  componentDidMount() {
    this.getImages();
  }

  getImages = async (after) => {
    if (this.loading) return;

    this.loading = true;

    const results = await MediaLibrary.getAssetsAsync({
      first: 20,
      after,
      sortBy: MediaLibrary.SortBy.creationTime,
    });

    const { assets, hasNextPage, endCursor } = results;

    this.setState({ images: this.state.images.concat(assets) }, () => {
      this.loading = false;
      this.cursor = hasNextPage ? endCursor : null;
    });
  };

  getNextImages = () => {
    // If there are no more pics to get, do nothing
    if (!this.cursor) return;

    /*
      If we don't check the above condition,
      once we reach the final of the camera roll,
      the beginning will be loaded again
    */

    this.getImages(this.cursor);
  };

  pickImage = (image) => {
    /*
      This method returns a boolean that indicates 
      if it was possible to select the image tapped by the user 
    */
    const { pickedImages } = this.state;

    // If the element is already in the list remove it
    if (isElementInList(image, pickedImages)) {
      this.setState({
        pickedImages: removeListElement(image, pickedImages),
      });

      return false;
    }

    // Do nothing if the user has already selected MAX_ALBUM_LENGTH images
    if (pickedImages.length === MAX_ALBUM_LENGTH) return false;

    // If the image is not currently picked, add it to the list of picked images
    if (!isElementInList(image, pickedImages)) {
      this.setState({
        pickedImages: [...pickedImages, image], // <----------------------------------------
      });

      return true;
    }
  };

  renderItem = ({ item: { uri }, size, marginTop, marginLeft }) => {
    const style = {
      width: size,
      height: size,
      marginLeft,
      marginTop,
    };

    const { pickedImages } = this.state;

    return (
      <Item
        uri={uri}
        onPress={this.pickImage}
        pickedImages={pickedImages}
        style={style}
      />
    );
  };

  render() {
    const {
      theme: { colors },
      handleClose,
      handleConfirm,
    } = this.props;

    const { images, pickedImages } = this.state;

    return (
      <>
        <View style={styles.topButtonsContainer}>
          <TouchableOpacity
            activeOpacity={0.5}
            style={styles.topButton}
            onPress={handleClose}
          >
            <Icon
              name="ios-close"
              type="ionicon"
              color={colors.black}
              size={40}
            />
          </TouchableOpacity>
          {pickedImages.length > 0 && (
            <TouchableOpacity
              activeOpacity={0.5}
              style={styles.topButton}
              onPress={handleConfirm}
            >
              <Icon
                name="ios-checkmark"
                type="ionicon"
                color={colors.black}
                size={40}
              />
            </TouchableOpacity>
          )}
        </View>
        <Grid
          data={images}
          keyExtractor={keyExtractor}
          renderItem={this.renderItem}
          initialNumToRender={20}
          removeClippedSubviews
          onEndReached={this.getNextImages}
        />
      </>
    );
  }
}

Pd:組件“Grid”只是一個 FlatList 包裝器

我唯一要做的就是將項目從 PureComponent 移動到 Component 並修改 shouldComponentUpdate 如下:

shouldComponentUpdate(nextProps, nextState) {
  // If the state "isSelected" has changed then update
  return nextState.isSelected !== this.state.isSelected;
}

暫無
暫無

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

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