Instantly share code, notes, and snippets.
Last active
August 12, 2022 08:47
-
Save ryanflorence/7de8c27474b299c6c2f357f785cfde77 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// src/entry-browser.js | |
import React from "react"; | |
import { unstable_createRoot as createRoot } from "react-dom"; | |
import Remix from "@remix-run/react/browser"; | |
import App from "./components/App"; | |
// default cache, every location gets its own data, even at the same pathname | |
function createLocationCache() { | |
return { | |
write({ cache, data, routeModule, location, params, routeId }) { | |
cache[location.key] = cache[location.key] || {}; | |
cache[location.key][routeId] = data; | |
return cache; | |
}, | |
read({ cache, params, routeModule, location, routeId }) { | |
return cache[location.key][routeId]; | |
}, | |
}; | |
} | |
// different locations but same pathname share the cache | |
function createPathnameCache() { | |
return { | |
write({ cache, data, routeModule, location, params, routeId }) { | |
cache[location.pathname] = cache[location.pathname] || {}; | |
cache[location.pathname][routeId] = data; | |
return cache; | |
}, | |
read({ cache, params, routeModule, location, routeId }) { | |
return cache[location.pathname][routeId]; | |
}, | |
}; | |
} | |
// delegate to the route modules themselves, each has the ability to change the | |
// entire cache, making it possible to normalize on writes so that data is | |
// completely independant of locations | |
function createRouteModuleDelegateCache() { | |
// can facilitate a normalized cache with normalizr, each route module can use | |
// the parts of the schema it needs so that the enitre schema isn't needed in | |
// the initial bundle | |
return { | |
write({ cache, data, routeModule }) { | |
return routeModule.writeData(cache, data); | |
}, | |
read({ cache, params, routeModule }) { | |
return routeModule.readData(cache, params); | |
}, | |
}; | |
} | |
// In a component, the setter for useRouteData will end up calling `cache.write` | |
function SomePage() { | |
let [routeData, setRouteData] = useRouteData(); | |
let someClickHandler = () => { | |
// will go to cache.write so should be shaped like the result of the route loader | |
let newData = {} | |
setRouteData(newData) | |
} | |
} | |
createRoot(document, { hydrate: true }).render( | |
// pass it in to remix, only need this in the browser because we can use | |
// the cache.write when we hydrate from the client handoff | |
<Remix cache={cache}> | |
<App /> | |
</Remix> | |
); | |
/////////////////////////////////// | |
// src/routes/Article.js | |
import React from "react"; | |
import { normalize, denormalize } from "normalizr"; | |
import { useRouteData } from "@remix-run/react"; | |
import { article } from "../schema"; | |
export function writeData(cache, data) { | |
let normalized = normalize(data, article); | |
return Object.assign({}, cache, normalized.entities); | |
} | |
export function readData(cache, params) { | |
return denormalize(params.articleId, article, cache); | |
} | |
export default function Article() { | |
let data = useRouteData(); | |
return <ArticlePage data={data} />; | |
} | |
// Data from the loader looks like this: | |
// { | |
// "id": "123", | |
// "author": { | |
// "id": "1", | |
// "name": "Paul" | |
// }, | |
// "title": "My awesome blog post", | |
// "comments": [ | |
// { | |
// "id": "324", | |
// "commenter": { | |
// "id": "2", | |
// "name": "Nicole" | |
// } | |
// } | |
// ] | |
// } | |
// normalizer normalizes it to this and they store `entities` as the cache | |
// { | |
// result: "123", | |
// entities: { | |
// "articles": { | |
// "123": { | |
// id: "123", | |
// author: "1", | |
// title: "My awesome blog post", | |
// comments: [ "324" ] | |
// } | |
// }, | |
// "users": { | |
// "1": { "id": "1", "name": "Paul" }, | |
// "2": { "id": "2", "name": "Nicole" } | |
// }, | |
// "comments": { | |
// "324": { id: "324", "commenter": "2" } | |
// } | |
// } | |
// } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment