Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/subrouter get static props #127

Merged
merged 1 commit into from
Nov 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/example-ssr/src/pages/FooPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useRef } from "react";
import React, { useRef } from "react";
import { useRouter, useStack } from "@cher-ami/router";
import { transitionsHelper } from "../helpers/transitionsHelper";
import { useLang } from "@cher-ami/router";
Expand Down
5 changes: 5 additions & 0 deletions examples/example-ssr/src/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ export const routes: TRoute[] = [
path: "/foo",
component: FooPage,
name: EPages.FOO,
getStaticProps: async () => {
const res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
const todo = await res.json();
return { todo };
},
},
{
path: "/bar",
Expand Down
76 changes: 40 additions & 36 deletions src/components/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -268,45 +268,49 @@ function Router(props: {
}

const newRoute: TRoute = matchingRoute || notFoundRoute;

// if no newRoute, do not continue
if (!newRoute) return;

if (props.initialStaticProps) {
const cache = staticPropsCache();

// check if new route data as been store in cache
const dataFromCache = cache.get(newRoute._fullUrl);

// first route visited (server & client)
const isFirstRouteVisited = newRoute._fullUrl === props.initialStaticProps.url;
log("is first route visited?", isFirstRouteVisited);

// In SSR context, we have to manage getStaticProps route properties from server and client
if (isFirstRouteVisited) {
log("newRoute.props", newRoute.props);
if (newRoute.props) {
Object.assign(newRoute.props, props.initialStaticProps?.props ?? {});
}
if (!dataFromCache) {
cache.set(newRoute._fullUrl, newRoute.props ?? {});
}
// store cache
const cache = staticPropsCache();
// check if new route data as been store in cache
const dataFromCache = cache.get(newRoute._fullUrl);
// first route visited (server & client)
const isFirstRouteVisited = newRoute._fullUrl === props.initialStaticProps?.url;
log(props.id, "is first route visited?", isFirstRouteVisited);

// Server and client
// check if is first route and initial static props exist
// in this case, we assign this response to newPage props and cache it
if (isFirstRouteVisited && props.initialStaticProps) {
log(
props.id,
"This is the first route & data exist in props.initialStaticProps, we assign and cache it.",
newRoute.props
);
if (newRoute.props) {
Object.assign(newRoute.props, props.initialStaticProps?.props ?? {});
}
// if NOT first route (client)
else {
// if cache exist for this route, assign it
if (dataFromCache) {
Object.assign(newRoute.props, dataFromCache);
}
// Continue only if getStaticProps is not undefined
else if (newRoute.getStaticProps) {
try {
const requestStaticProps = await newRoute.getStaticProps(newRoute.props);
Object.assign(newRoute.props, requestStaticProps);
cache.set(newRoute._fullUrl, requestStaticProps);
} catch (e) {
console.error("requestStaticProps failed");
}
cache.set(newRoute._fullUrl, newRoute.props ?? {});
}
// Client only (not the first route, it only can be the client)
// Case, is not first route OR no initial static props:
// If cache exist for this route, assign it and continue.
// else, we request the static props and cache it
else {
if (dataFromCache) {
log(props.id, "Not first route & no initialStaticProps > assign dataFromCache");
Object.assign(newRoute.props, dataFromCache);
} else if (newRoute.getStaticProps) {
log(
props.id,
"Not first route & no initialStaticProps & no dataFromCache > request getStaticProps"
);
try {
const requestStaticProps = await newRoute.getStaticProps(newRoute.props);
Object.assign(newRoute.props, requestStaticProps);
cache.set(newRoute._fullUrl, requestStaticProps);
} catch (e) {
console.error("requestStaticProps failed");
}
}
}
Expand Down