如何仅重新渲染平面列表中的一项?

uni*_*e11 7 reactjs react-native

我有带有星号图标的产品,可以将此产品添加到愿望清单中。我映射了 10 个产品列表,每个映射有 3 个产品,例如:

(我将其映射到 Pagerview 以滑动到下一个产品)

产品组件

const ListProducts = [
  {
    id: 1,
    products: [{
      product_id: 1,
      photos: [...]
    }]
  },
  {
    id: 2,
    products: [{
      product_id: 1,
      photos: [...]
    }]
  }
  {
    id: 3,
    products: [{
      product_id: 1,
      photos: [...]
    }]
  },
  {
    id: 4,
    products: [{
      product_id: 1,
      photos: [...]
    }]
  }
...
];


function isEq(prev, next) {
  if(prev.is_wishlist === next.is_wishlist) {
    return true;
  }
}

const Item = memo(({ id, photos, is_wishlist, onPress, onPressWishlist }) => {
  const findProductIdInWishList = is_wishlist.find((el => el.product_id === id));
  return (
    <Button style={s.imgBtn} onPress={() => onPress(id)}>
      <Button onPress={() => onPressWishlist(id)} style={s.starBtn}>
        <AntDesign name={findProductIdInWishList ? 'star' : 'staro'} size={20} color={globalStyles.globalColor} />
      </Button>
      <ImageSlider photos={photos} />
    </Button>
  )
  // @ts-ignore
}, isEq);

  const wishlist = useSelector((state) => state.WishList.wishlist);
  const dispatch = useDispatch();

  const renderItem: ListRenderItem<IProduct> = ({ item }) => (
    <Item
      id={item.id}
      photos={item.photos}
      is_wishlist={wishlist}
      onPressWishlist={handlePressWishList}
    />
  )


  const handlePressWishList = (product_id: string) => {
    dispatch(addAndRemoveProductToWishList({product_id}));
  };
Run Code Online (Sandbox Code Playgroud)

产品组件列表

Products Map:

      <PagerView onPageSelected={(e) => handleSetAllIndexes(e.nativeEvent.position)} style={s.container} initialPage={index}>
      {
        allProducts.map((el, i) => (
          <View style={s.viewsContainer} key={i}>
            { allIndex.includes(i) ? (
              <View style={s.viewsInnerContainer}>
                { /* products */ }
                <Products products={el.products as IProduct[]} total_price={el.total_price} product_name={el.packet_name} />
              </View>
              ) : (
              <View style={s.loadingContainer}>
                <Loader size={'large'} color='#fff' />
              </View>
              )
            }
          </View>)
        )
      }
      </PagerView>
Run Code Online (Sandbox Code Playgroud)

如果我点击星形图标,它的调度会很快,但如果我刷到其他产品,可能会一直到最后,然后我按星形图标进行调度,然后它会出现延迟/滞后,您可以看到它

我没有添加完整的代码,因为有一些与问题无关的片段。

附:

视频

Fou*_*our 1

我将编辑我的答案而不是发表评论。在我的代码之前,让我先解释一下。在您当前的代码中,每当“allProducts”更改时,所有内容都会重新呈现。每当“allIndex”发生变化时,所有内容也会重新渲染。列表越长,滞后就越多。
在这种情况下你可以尝试“useCallback”吗?

const renderItem = React.useCallback((el, i) => (
  <View style={s.viewsContainer} key={i}>
      {allIndex.includes(i) ? (
        <View style={s.viewsInnerContainer}>
          <Products />
        </View>
      ) : (
        <Loading />
      )}
    </View>
),[allIndex])

{allProducts.map(renderItem)}
Run Code Online (Sandbox Code Playgroud)

现在,当“allIndex”更改时,renderItem 将重新渲染。我仍然推荐使用带有“horizo​​ntal={true}”和“某些样式”的“FlatList”,而不是“PagerView”。如果仍然想使用“PagerView”,那么“Lazy”组件怎么样?“惰性组件”在组件进入用户视图之前不会渲染它们。因此,在它们被看到之前,它们不会参与重新红化。