'React Recoil: State not being saved across navigation to different URLs within App

I'm getting started with Recoil for a React App, but running into some issues, or at least some behavior I'm not expecting.

I'd like to be able to use one component to render many different "views" based on the URL. I have a useEffect in this component that switches based on the location.pathname and based on that pathname, it'll make an API call. But before it makes the API call, it checks the length of the atom to see if it's empty or not, then will call the API and set the atom based on the API call.

However, when I navigate to a different URL and come back to one I've already visited, the API is called again, even though I've previously set the state for that URL.

The behavior I'm expecting is that once a URL has been visited and the return from the API is stored in an Atom, the API call isn't made again when leaving the URL and coming back.

Relevant code below:

Atom.js

export const reports = atom({ key: "reports", default: { country: [], network: [], }, });

the one component that will render different data based on the reports atom.

import { useRecoilState } from "recoil";
import { reports } from "../globalState/atom";

const TableView = ({ columns, }) => {
  const location = useLocation();
  const [report, setReport] = useRecoilState(reports);


  const currentView = location.pathname.split("/")[1];

useEffect(() => {
    const getReportsData = async () => {
      switch (location.pathname) {
        case "/network":
 
          if (report[currentView].length === 0) {
            const response = await fetch("/api");
            const body = await response.json(); 
                
                        setReport(
              Object.assign({}, report, {
                [currentView]: body,
              })
            );
        console.log('ran')
        break;
     }
   getReportsData();
   }, [])

As previously mentioned, that console.log is ran every time I navigate to /network, even if I've already visited that URL.

I've also tried doing this with selectors.

Atom.js

export const networkState = atom({
  key: "networkState",
  default: networkSelector,
});

export const networkSelector = selector({
  key: "networkSelector",
  get: async ({ get }) => {

    try {
      const body = await fetch("/api/network").then((r) => r.json());
      return body;
    
} catch (error) {
      console.log(error);
      return [];
    }
  }

Component

import {useRecoilStateLoadable} from "recoil"
import {networkState} from "../globalState/atom";

const Table = ({columns}) => {

  const [networkData, setNetworkData] =
    useRecoilStateLoadable(networkState);

And then a switch statement based on networkData.state

}

Any help would be greatly appreciated, thank you!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source