Flat list re-rendering when state change

51 Views Asked by At

this is my component when the liked state change imported from mobx, the function handleLikeSubject takes time to finish the execution due to the re-render of the FlatList, how can I get rid of the re-render?

This is the code of the parent component:

import { View, Text, FlatList } from "react-native";
import React, { useContext, useCallback } from "react";
import { I18nContext } from "../../Context/I18nContext";
import { authStore } from "../../MobX/AuthStore";
import useFetch from "../../ReusbaleTools/Functions/UseFetch";
import Loading from "../../ReusbaleTools/Components/Loading";
import FavSubject from "../../Components/FavSubject";
import { likedSubjectStore } from "../../MobX/LikedSubjectsStore";
import { observer } from "mobx-react";

const Intro = observer(() => {
  const { i18n } = useContext(I18nContext);

  const { liked, setLikedSubjects, loading } = likedSubjectStore;

  const { userInfo } = authStore;

  const { data, isLoading } = useFetch("get_firstrun_subjects_new", {
    user_id: `${userInfo.ID}`,
  });

  const renderItems = useCallback(
    ({ item }) => {
      const isLiked = liked.some((likedSubject) => likedSubject.ID === item.ID);

      return (
        <FavSubject
          {...item}
          key={item.key}
          liked={isLiked}
          onPress={() => handleLikeSubject(item, isLiked)}
        />
      );
    },
    [liked, handleLikeSubject]
  );

  const subjects = data && data?.subjects;

  const handleLikeSubject = (subject, isLiked) => {
    let updatedLikedSubjects;

    if (isLiked) {
      // If already liked, unlike it
      updatedLikedSubjects = liked.filter((id) => id.ID !== subject.ID);
    } else {
      // If not liked, like it
      updatedLikedSubjects = [subject, ...likedSubjectStore.liked];
    }

    setLikedSubjects(updatedLikedSubjects);
  };

  if (isLoading || loading) {
    return <Loading />;
  }

  return (
    <View className="flex-1">
      <Text className="p-3 text-[20px] text-center font-regular bg-white">
        {i18n.t("intro.choose")}
      </Text>

      <View className="pt-5 flex-1">
        {subjects && (
          <FlatList
            data={subjects}
            keyExtractor={(item) => item.ID}
            renderItem={renderItems}
            numColumns={2}
            showsVerticalScrollIndicator={false}
          />
        )}
      </View>
    </View>
  );
});

export default Intro;

This one for the children:

import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
import { MaterialIcons } from "@expo/vector-icons";
import { memo, useCallback } from "react";

const FavSubject = memo(({ onPress, title, liked }) => {
  const memoizedOnPress = useCallback(onPress, [onPress]);

  return (
    <TouchableOpacity onPress={memoizedOnPress}>
      <View
        className="flex-row items-center bg-white w-[160px] h-[60px] mx-4 mb-5"
        style={[
          styles.card,
          {
            backgroundColor: !liked ? "#ECEDF1" : "white",
          },
        ]}
      >
        <MaterialIcons name="arrow-right" size={34} color="#666666" />
        <Text className="text-base font-regular max-w-[130px] text-center">
          {title}
        </Text>
      </View>
    </TouchableOpacity>
  );
});

export default FavSubject;

const styles = StyleSheet.create({
  card: {
    borderRadius: 8,
    elevation: 4,
  },
});

I tried with useCallback with dependecies and without dependecies and nothing changed.

0

There are 0 best solutions below