Search code examples
reactjsreduxreact-reduxuse-effectredux-thunk

React Prevent re-fetching on page changing


i'm currently working on a react app that fetches some content from my backend, which results to be very heavy. My intention is to keep the component alive and prevent re-render every time the user changes from one page to another. Currently i'm fetching all data and storing it with react-redux and thunk.

I'd like to keep the refresh option though via a button click.

I've tried wrapping the component inside a React.memo component but had no luck.

Here is my code in case you may help me:

This is the component i'd like to not re render unless the refresh state changes:

import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { getNFTs } from "../../actions/NFT";

export const LandList = React.memo(() => {
  const { gettingNFTs, NFTs } = useSelector((state) => state.NFT);
  const [refresh, setRefresh] = useState(0);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(getNFTs());
  }, []);

  return (
    <div>
      <h2>LandList</h2>
      {gettingNFTs ? <p>getting nfts...</p> : <p>Done</p>}
    </div>
  );
});

And this is my action to the store (i use thunk here):

export const getNFTs = () => {
  return async (dispatch) => {
    dispatch(getNFTsAction());

    const resp = await fetchWithoutToken("marketplace");
    const body = await resp.json();

    dispatch(finishGetNFTsAction(body.publishedLands));
    console.log(body);
  };
};

const getNFTsAction = () => ({
  type: types.NFTsGetStart,
});

const finishGetNFTsAction = (NFT) => ({
  type: types.NFTsGetFinished,
  payload: NFT,
});

Any help would be greatly appreciated!


Solution

  • You can use redux or context hook to do it, create a global flag and change it after the first successful request, and make a condition inside useEffect hook

    export const LandList = React.memo(() => {
      const { gettingNFTs, NFTs } = useSelector((state) => state.NFT);
      const [refresh, setRefresh] = useState(0);
      const dispatch = useDispatch();
    
      useEffect(() => {
      // here is the global variable or property , check it before your dispatch
       if(!fetched){ 
        dispatch(getNFTs());
       }
      }, []);
    
      return (
        <div>
          <h2>LandList</h2>
          {gettingNFTs ? <p>getting nfts...</p> : <p>Done</p>}
        </div>
      );
    });