React Native FlatList正在多次渲染项目

ctrmrzij  于 2023-10-22  发布在  React
关注(0)|答案(1)|浏览(169)

控制台日志显示“TrendingMovies”是一个调用API的组件,“ListItem 1”是另一个用于呈现列表项的组件。在日志中,您可以观察到它多次呈现索引0到10。
控制台日志-

TrendingMovies renders
 LOG  getMovies called
 LOG  cooode
 LOG  TrendingMovies renders
 LOG  TrendingMovies renders
 LOG  ListItem1 : 0
 LOG  ListItem1 : 1
 LOG  ListItem1 : 2
 LOG  ListItem1 : 3
 LOG  ListItem1 : 4
 LOG  ListItem1 : 5
 LOG  ListItem1 : 6
 LOG  ListItem1 : 7
 LOG  ListItem1 : 8
 LOG  ListItem1 : 9
 LOG  ListItem1 : 0
 LOG  ListItem1 : 1
 LOG  ListItem1 : 2
 LOG  ListItem1 : 3
 LOG  ListItem1 : 4
 LOG  ListItem1 : 5
 LOG  ListItem1 : 6
 LOG  ListItem1 : 7
 LOG  ListItem1 : 8
 LOG  ListItem1 : 9
 LOG  ListItem1 : 10
 LOG  ListItem1 : 11
 LOG  ListItem1 : 12
 LOG  ListItem1 : 13
 LOG  ListItem1 : 14
 LOG  ListItem1 : 15
 LOG  ListItem1 : 16
 LOG  ListItem1 : 17
 LOG  ListItem1 : 18
 LOG  ListItem1 : 19

这里是组件代码-

type Props = {};

const TrendingMovies = (props: Props) => {
  const [movies, setMovies] = useState<TrendingMoviesType[]>([]);
  const [currentPage, setCurrentPage] = useState(1);
  const [isLoading, setIsLoading] = useState(false);
  const [isError, setIsError] = useState<string | null>(null);
  const navigation = useNavigation<homeScreenNavigationProp>();

  console.log('TrendingMovies renders');

  useEffect(() => {
    console.log('getMovies called');
    getMovies();
  }, []);

  const getMovies = async () => {
    console.log('cooode');
    setIsLoading(true);
    const result = await trendingMoviesService(currentPage);
    if (result.sucess) {
      setMovies(result.value);
    } else {
      setIsError(result.error.message);
    }
    setIsLoading(false);
  };

  function onItemTap() {
    console.log('onItemTap');
    navigation.navigate('ViewAll');
  }

  const onListItemTap = (id: string) => {
    console.log('onListItemTap');
    navigation.push('MovieDetail', {id: id});
  };

  return (
    <View>
      {isLoading ? (
        <MoviesLoadingPlaceholder />
      ) : isError !== null ? (
        <View></View>
      ) : (
        <View style={styles.listContainer}>
          <View style={styles.headerRow}>
            <AppText
              text={'Trending now'}
              textType="sectionTitle"
              style={styles.sectionTitle}
            />
            <TouchableOpacity onPress={onItemTap}>
              <AppText
                text={'View All'}
                textType="regular"
                style={styles.sectionTitle}
              />
            </TouchableOpacity>
          </View>
          <FlatList
            data={movies}
            renderItem={({item, index}) => (
              <ListItem1
                index={index}
                image={item.poster_path}
                onTap={() => onListItemTap(item.id.toString())}
              />
            )}
            keyExtractor={item => item.id.toString()}
            horizontal={true}
            showsHorizontalScrollIndicator={false}
          />
        </View>
      )}
    </View>
  );
};

export default TrendingMovies;

这里是ListItem 1组件-

type Props = {
  image: string;
  onTap: () => void;
  index: number;
};

const ListItem1 = ({index, image, onTap}: Props) => {
  console.log('ListItem1 : ' + index);
  return (
    <View>
      <TouchableOpacity onPress={onTap}>
        <AppImage imageURL={baseImageURL + image} />
      </TouchableOpacity>
    </View>
  );
};

export default ListItem1;

预期的输出是每个“ListItem 1”应该只呈现一次。

3xiyfsfu

3xiyfsfu1#

在尝试了很多解决方案之后,我能够通过如下所示更改内联箭头函数并在导出时将组件 Package 在memo中来修复它。
从-

onTap={() => onListItemTap(item.id.toString())}

对此-

onTap={onListItemTap}

现在ListItem 1看起来像这样-

<ListItem1
        id={item.id.toString()}
        index={index}
        image={item.poster_path}
        onPress={onListItemTap}
      />

并在出口时将其 Package 在备忘录中-

export default memo(ListItem1);

把日志记录下来-

LOG  ListItem1 : 0
 LOG  ListItem1 : 1
 LOG  ListItem1 : 2
 LOG  ListItem1 : 3
 LOG  ListItem1 : 4
 LOG  ListItem1 : 5
 LOG  ListItem1 : 6
 LOG  ListItem1 : 7
 LOG  ListItem1 : 8
 LOG  ListItem1 : 9
 LOG  ListItem1 : 10
 LOG  ListItem1 : 11
 LOG  ListItem1 : 12
 LOG  ListItem1 : 13
 LOG  ListItem1 : 14
 LOG  ListItem1 : 15
 LOG  ListItem1 : 16
 LOG  ListItem1 : 17
 LOG  ListItem1 : 18
 LOG  ListItem1 : 19

相关问题