0

When i click for navigation before fetching complete i facing the below warning. How can i solve this problem

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s, a useEffect cleanup function

const SearchResultScreen = ({ navigation, route }) => {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [modalVisible, setModalVisible] = useState(false);
  const [selectedValue, setSelectedValue] = useState("lastHour");

  const dispatch = useDispatch();
  const newsies = useSelector((state) => state.searchResult.newsies);

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      await dispatch(getSearchResults());
      setError(null);
    } catch (e) {
      setError("Something went wrong!");
    }
    setLoading(false);
  }, []);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  useLayoutEffect(() => {
    navigation.setOptions({
      headerTitle: () => (
        <TouchableWithoutFeedback onPress={() => navigation.replace("Search")}>
          <Text numberOfLines={1} style={styles.searchBtnText}>
            {route.params ? route.params.itemValue : ""}
          </Text>
        </TouchableWithoutFeedback>
      ),
      headerRight: () => (
        <HeaderButtons>
          <HeaderButton
            iconName="sliders"
            onPressed={() => {
              setModalVisible(true);
            }}
            style={{
              transform: [{ rotate: "-90deg" }],
              backgroundColor: "transparent",
            }}
          />
        </HeaderButtons>
      ),
    });
  }, [navigation, route]);

  if (loading) {
    return <CenteredSpinner />;
  }
  if (!loading && error) {
    return <CenteredErrorBox errorMsg={error} onPressed={fetchData} />;
  }
  if (!loading && newsies.length === 0) {
    return <CenteredErrorBox errorMsg={"No Data Found!"} />;
  }
  return (
    <>
      <CustomModal
        onClosed={() => setModalVisible(false)}
        modalVisible={modalVisible}
      >
        <Text style={styles.CustomModalTitle}>Search Filter</Text>
        <View style={styles.CustomModalBody}>
          <View style={styles.CustomModalBodyFilter}>
            <Text style={styles.CustomModalBodyFilterText}>Published at</Text>
            <CustomPicker
              items={[
                ["Last hour", "lastHour"],
                ["Last Day", "lastDay"],
                ["Last Week", "lastWeek"],
              ]}
              selectedValue={selectedValue}
              onValueChanged={(itemValue) => setSelectedValue(itemValue)}
            />
          </View>
        </View>
        <View style={styles.CustomModalActions}>
          <RippleButton
            style={{ marginRight: 10 }}
            onPressed={() => {
              setModalVisible(false);
            }}
          >
            <Text style={styles.CustomModalActionsBtn}>CANCEL</Text>
          </RippleButton>
          <RippleButton onPressed={() => {}}>
            <Text style={styles.CustomModalActionsBtn}>APPLY</Text>
          </RippleButton>
        </View>
      </CustomModal>
      <FlatList
        initialNumToRender={10}
        showsVerticalScrollIndicator={!Platform.OS === "android"}
        style={styles.list}
        renderItem={({ item }) => (
          <NewsBox
            news={item}
            onPressed={() => navigation.navigate("NewsDetail")}
          />
        )}
        data={newsies}
      />
    </>
  );
};
Sibiraj
  • 4,486
  • 7
  • 33
  • 57

1 Answers1

1

useEffect hook may return the function which will be called once when the component is being unmounted to clean up async tasks and subscribes.

useEffect(()=>{
  // do some usefull staff here, for example subscribing or fetching data:
  ...
  // return cleaning function which will cancel subscribes and uncompleted fetches:
  return () => {
    ...
  }

}, [])

To cancel fetch or any other async things you can try AbortController.

Tarukami
  • 1,160
  • 5
  • 8