Home > Software design >  Using Contexts that take props with React Router
Using Contexts that take props with React Router

Time:11-19

I have an application that is tracking information about various servers. I have a web server that I am able to query for the information by server name. I created a context for this information that takes a server name as a prop and updates its data periodically. See below;

ServerContext.js

export const ServerDataContext = createContext();

export const ServerDataContextProvider = ({
  children,
  server= "",
}) => {
  const [serverConfig, setServerConfig] = useState({});

  const updateServerData = () => {;
    serverConfigRequest(server).then((res) => {
      setServerConfig((old) => {
        return res;
      });
    });
  };

  useEffect(() => {
    console.log("init");
    updateServerData();
    const updateInterval = setInterval(
      updateServerData,
      serverConfigUpdateFrequency * 1000
    );

    return () => {
      clearInterval(updateInterval);
    };
  }, []);

  return (
    <ServerDataContext.Provider
      value={{
        serverConfig,
      }}
    >
      {children}
    </ServerDataContext.Provider>
  );
};

In my App.js I use react router to for having a StatusPage for each server. It looks something like this:

App.js

function App() {
  return (
    <Router>
      <div className="app">
        <Header />
        <Routes>
          <Route exact path="/" element={<div>Overview</div>} />
          <Route
            exact
            path="/server_1"
            element={
              <ServerDataContextProvider server="server_1">
                <StatusPage server="server_1" />
              </ServerDataContextProvider>
            }
          />
          <Route
            exact
            path="/server_2"
            element={
              <ServerDataContextProvider server="server_2">
                <StatusPage server="server_2" />
              </ServerDataContextProvider>
            }
          />
        </Routes>
        <Footer />
      </div>
    </Router>
  );
}

I have buttons to go to each page in the header. When I load up the first servers status page the page updates perfectly fine. I see requests on my server coming in at the correct interval for server_1. Then I navigate to server_2 I see the route update in my browser search bar but the content on the page does not. The requests I am receiving on my web server are still for server_1 at the same interval as though i hadnt switched pages. If i refresh the page still at the endpoint for server_2 the content on the page will update properly for server_2 but the same issue occurs with server_1 this time.

Am I using contexts inappropriately? I think the problem is how I have the app structured but am not sure. Any advice is appreciated.

Edit: Edit using-contexts-that-take-props-with-react-router

enter image description here enter image description here

Alternatively, adding the server prop as a dependency in the ServerDataContextProvider's useEffect hook will also clear any existing interval timers and restart them with the updated server prop's value.

useEffect(() => {
  // moved into effect callback to remove as dependency
  const updateServerData = () => {
    setServerConfig((old) => {
      return { server: server == "server_1" ? "G" : "R" };
    });
  };

  console.log("init");
  updateServerData();
  const updateInterval = setInterval(updateServerData, 5 * 1000);

  return () => {
    clearInterval(updateInterval);
  };
}, [server]);
  • Related