diff --git a/client/src/App.tsx b/client/src/App.tsx
index b6ed4c2b..ba50bc42 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -1,42 +1,14 @@
import "./App.css";
-import { ControlPoint } from "./api/controlpoint";
-import { Flight } from "./api/flight";
import { LatLng } from "leaflet";
import LiberationMap from "./components/liberationmap";
-import axios from "axios";
-import { registerFlight } from "./api/flightsSlice";
-import { setControlPoints } from "./api/controlPointsSlice";
-import { useAppDispatch } from "./app/hooks";
-import { useEffect } from "react";
+import { useInitialGameState } from "./api/useInitialGameState";
function App() {
const mapCenter: LatLng = new LatLng(25.58, 54.9);
- const dispatch = useAppDispatch();
+ useInitialGameState();
- useEffect(() => {
- axios
- .get("http://[::1]:5000/control-points")
- .catch((error) => console.log(`Error fetching control points: ${error}`))
- .then((response) => {
- if (response != null) {
- dispatch(setControlPoints(response.data as ControlPoint[]));
- }
- });
- axios
- .get("http://[::1]:5000/flights?with_waypoints=true")
- .catch((error) => console.log(`Error fetching flights: ${error}`))
- .then((response) => {
- if (response != null) {
- for (const flight of response.data) {
- dispatch(registerFlight(flight as Flight));
- }
- }
- });
- });
-
- console.log(`mapCenter=${mapCenter}`);
return (
diff --git a/client/src/api/backend.ts b/client/src/api/backend.ts
new file mode 100644
index 00000000..7835e3b1
--- /dev/null
+++ b/client/src/api/backend.ts
@@ -0,0 +1,7 @@
+import axios from "axios";
+
+export const backend = axios.create({
+ baseURL: "http://[::1]:5000/",
+});
+
+export default backend;
diff --git a/client/src/api/useInitialGameState.tsx b/client/src/api/useInitialGameState.tsx
new file mode 100644
index 00000000..c400b865
--- /dev/null
+++ b/client/src/api/useInitialGameState.tsx
@@ -0,0 +1,39 @@
+import { ControlPoint } from "./controlpoint";
+import { Flight } from "./flight";
+import backend from "./backend";
+import { registerFlight } from "./flightsSlice";
+import { setControlPoints } from "./controlPointsSlice";
+import { useAppDispatch } from "../app/hooks";
+import { useEffect } from "react";
+
+// TODO: This should probably be distinct useControlPoints, useFlights, etc that
+// are smart enough to only initialize once which get called in the components
+// that use them rather than forcibly loading the whole game in the root
+// component.
+export function useInitialGameState() {
+ const dispatch = useAppDispatch();
+ useEffect(() => {
+ return () => {
+ backend
+ .get("/control-points")
+ .catch((error) =>
+ console.log(`Error fetching control points: ${error}`)
+ )
+ .then((response) => {
+ if (response != null) {
+ dispatch(setControlPoints(response.data as ControlPoint[]));
+ }
+ });
+ backend
+ .get("/flights?with_waypoints=true")
+ .catch((error) => console.log(`Error fetching flights: ${error}`))
+ .then((response) => {
+ if (response != null) {
+ for (const flight of response.data) {
+ dispatch(registerFlight(flight as Flight));
+ }
+ }
+ });
+ };
+ });
+}
diff --git a/client/src/index.tsx b/client/src/index.tsx
index 1fac9c77..3468b9c5 100644
--- a/client/src/index.tsx
+++ b/client/src/index.tsx
@@ -1,10 +1,12 @@
+import "./index.css";
+
+import * as serviceWorker from "./serviceWorker";
+
+import App from "./App";
+import { Provider } from "react-redux";
import React from "react";
import ReactDOM from "react-dom";
-import "./index.css";
-import App from "./App";
import { store } from "./app/store";
-import * as serviceWorker from "./serviceWorker";
-import { Provider } from "react-redux";
ReactDOM.render(