I am using axios to get an array from a JSON file and I want to use the same array over multiple nodes / pages.
Currently I’m using this on each page var printers = GetPrinters();
I was trying call GetPrinters()
from the App.tsx and pass it to each page via a router but I couldn’t seem to get that to work. Is there a way I can store the array on state and access it on any node?
I plan to make 4 more pages similar to MonoPrints.tsx that all need access to the data from the array, they won’t be updating the array at all, just accessing it.
I would like to use the best practice for this kind of thing and am stuck with repeating the call for each page at the moment.
Site Structure:
App.tsx
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { TonerLevels } from "./pages/TonerLevels";
import { MonoPrints } from "./pages/MonoPrints";
import { MonoCopies } from "./pages/MonoCopies";
import { ColourPrints } from "./pages/ColourPrints";
import { ColourCopies } from "./pages/ColourCopies";
export function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/TonerLevels" element={<TonerLevels />}></Route>
<Route path="/MonoPrints" element={<MonoPrints />}></Route>
<Route path="/MonoCopies" element={<MonoCopies />}></Route>
<Route path="/ColourPrints" element={<ColourPrints />}></Route>
<Route path="/ColourCopies" element={<ColourCopies />}></Route>
</Routes>
</BrowserRouter>
);
}
Pages/
TonerLevels
export function TonerLevels() {
var printers = GetPrinters();
return (
<div>
<Nav></Nav>
<table className="table table-dark table-hover">
<thead>
<tr>
<th>Location</th>
<th>IP</th>
<th>Name</th>
<th>Serial</th>
<th>Black %</th>
<th>Yellow %</th>
<th>Magenta %</th>
<th>Cyan %</th>
<th>K1 %</th>
<th>K2 %</th>
<th>Current Monthly Prints</th>
<th>Current Monthly Copies</th>
</tr>
</thead>
<tbody className="table-group divider">
{printers
? printers.map((printer) => {
return (
<tr key={printer.address}>
<td>{printer.location}</td>
<td>
<a
href={"//" + printer.address}
target="_blank"
rel="noopener noreferrer"
>
{printer.address}
</a>
</td>
<td>{printer.name}</td>
<td>{printer.serial}</td>
<td>{printer.black > -1 ? printer.black : ""}</td>
<td>{printer.yellow > -1 ? printer.yellow : ""}</td>
<td>{printer.magenta > -1 ? printer.magenta : ""}</td>
<td>{printer.cyan > -1 ? printer.cyan : ""}</td>
<td>{printer.k1 > -1 ? printer.k1 : ""}</td>
<td>{printer.k2 > -1 ? printer.k2 : ""}</td>
<td>{getPrints(printer)}</td>
<td>{getCopies(printer)}</td>
</tr>
);
})
: null}
</tbody>
</table>
</div>
);
}
Services/
PrinterServices
import axios from "axios";
import { useEffect, useState } from "react";
const PRINTER_REST_API_URL = "http://localhost:8080/GetReport";
export interface Printer {
address: string;
black: number;
monoCopies: number;
monoPrints: number;
colourCopies: number;
colourPrints: number;
cyan: number;
k1: number;
k2: number;
location: string;
magenta: number;
name: string;
serial: string;
yellow: number;
Reports: [
{
month: string;
monoPrints: number;
monoCopies: number;
colourPrints: number;
colourCopies: number;
}
];
}
export function GetPrinters() {
const [printers, setPrinters] = useState<Printer[] | null>();
useEffect(() => {
axios.get(PRINTER_REST_API_URL).then((response) => {
setPrinters(response.data);
});
}, []);
return printers;
}
2
Answers
Yes, there are options available to maintain state at higher level and consume it across the components.
Context API
– helps passing data deeply into the tree and can be accessible only within the hierarchy. (Official doc: https://react.dev/reference/react/useContext).React Redux
– Manages state at app level and can be accessible from any components. (Official doc: https://redux-toolkit.js.org/introduction/getting-started)Option 1 can be used for your case as it looks simpler and manageable.
Option 2 can be used for large scale application with complex state management.
You can use "React Context" to store the array on a global state and then access it from any component.
Context code would look like this in Javascript:
Then add ContextProvider in your app.js
Now you can simply use
useContext
hook to access the printers state from any component.