Skip to content

Instantly share code, notes, and snippets.

@benbarber
Last active October 11, 2023 12:49
Show Gist options
  • Save benbarber/d9e7511d97cdd5b273e368a2472d3d40 to your computer and use it in GitHub Desktop.
Save benbarber/d9e7511d97cdd5b273e368a2472d3d40 to your computer and use it in GitHub Desktop.
ueStrictLoaderData - Adds a warning to the console for any data sent from the loader and not used
import { useLoaderData } from "@remix-run/react";
import { useEffect } from "react";
export const useStrictLoaderData = () => {
const data = useLoaderData();
const accessed = [] as String[];
const getAllKeys = (obj: any, path = "") => {
const keys = [] as String[];
Object.keys(obj).forEach((k: string) => {
if (typeof obj[k] === "object") {
getAllKeys(obj[k], `${path}.${k}`).forEach((sk) => {
keys.push(sk);
});
} else {
keys.push(`${path}.${k}`);
}
});
return keys;
};
const createHandler = (path: string) => {
return {
path,
get(target: any, prop: string, receiver: any) {
accessed.push(`${path}.${prop}`);
return Reflect.get(target, prop, receiver);
},
};
};
const createProxy: any = (obj: any, path = "") => {
let strictData: any = {};
Object.keys(obj).forEach((k: string) => {
if (typeof obj[k] === "object") {
strictData[k] = createProxy(obj[k], `${path}.${k}`);
} else {
strictData[k] = obj[k];
}
});
return new Proxy(strictData, createHandler(path));
};
const strictLoaderData = createProxy(data);
useEffect(() => {
getAllKeys(data).forEach((k) => {
if (!accessed.includes(k)) {
console.warn(
`useStrictLoaderData: You sent ${k} from the loader but did not use it`,
);
}
});
});
return strictLoaderData;
};
@benbarber
Copy link
Author

This was just for a proof of concept, it needs updating more for full type safety and should full back to just returning useLoaderData when creating a production build.

@benbarber
Copy link
Author

Screenshot 2023-10-11 at 13 25 43

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment