Refetching data

By default, Rakkas only calls the load function under the following circumstances:

  • When a page or layout is being rendered on the server side.
  • When client-side navigation causes a page or layout change. Only the load functions of the page component and those of the newly mounted layout components will be called. If a layout is shared between the previous and next page, it will stay mounted and won't be reloaded.
  • Only for pages: When the URL path or query string (url.pathname and url.search) changes. Layouts are not affected.
  • Only during development: When a page or layout module is hot reloaded.

There are three methods for changing the reloading behavior:

getCacheKey function

You can have a getCacheKey function in the object you pass to definePage or defineLayout. It is passed the same arguments as the load function except for fetch. Its return value can be anything that can be serialized into JSON. Rakkas will call it everytime it has to decide whether to call the load function and will only call it if the return value is different than the last time.

For example, you can tell Rakkas to call a page's load function only when the URL path changes and not when the query string changes:

import React from "react";
import { definePage } from "rakkasjs";

definePage({
	// Return url.pathname as the cache key
	getCacheKey: ({ url }) => url.pathname,

	// This will now only be called when url.pathname changes.
	// It won't be called when url.search changes.
	load() {
		return { data: undefined };
	},

	Component: function PageWithCustomCacheKey() {
		return <p>...</p>;
	},
});

Or you can force Rakkas to call your layout's load function when the URL path changes:

import React from "react";
import { defineLayout } from "rakkasjs";

defineLayout({
	// Return url.pathname as the cache key
	getCacheKey: ({ url }) => url.pathname,

	// This will now be called when url.pathname changes.
	load() {
		return { data: undefined };
	},

	Component: function LayoutWithCustomCacheKey() {
		return <p>...</p>;
	},
});

reload function

Page and layout components are passed a reload prop which you can use to manually force Rakkas to call its load function and rerender it:

import React from "react";
import { Page, PageLoadFunc } from "rakkasjs";
import { Helmet } from "react-helmet-async";

export const load: PageLoadFunc = () => {
	return {
		data: Math.floor(1000 * Math.random()),
	};
};

const RandomDataPage: Page = ({ data, reload }) => (
	<div>
		<Helmet title="load and reload Example - Rakkas" />
		<p>
			Data is: <b>{data}</b>.
		</p>
		<button onClick={() => reload()}>Reload</button>
	</div>
);

export default RandomDataPage;
Rakaks Demo App

useReload custom hook

Page and layout components are passed a useReload function which is a React custom hook used to force a reload under certain conditions:

import React from "react";
import { definePage, DefinePageTypes } from "rakkasjs";
import { Helmet } from "react-helmet-async";

type UseReloadPageTypes = DefinePageTypes<{
	data: number;
}>;

export default definePage<UseReloadPageTypes>({
	load() {
		return {
			data: Math.floor(1000 * Math.random()),
		};
	},

	Component: function UseReloadPage({ data, reload, useReload }) {
		useReload({
			// Reload when the window comes to foreground
			focus: true,
			// Reload when the internet connection is restored after a disconnection
			reconnect: true,
			// Reload every two seconds
			interval: 2000,
			// But only if the window is in the foreground
			background: false,
		});

		return (
			<div>
				<Helmet title="useReload Example - Rakkas" />
				<p>
					Data is: <b>{data}</b>.
				</p>
				<button
					onClick={() => {
						// Manually force reload
						reload();
					}}
				>
					Reload
				</button>
			</div>
		);
	},
});
Rakaks Demo App

Static site generation

reload and useReload are no-ops on a statically exported page since its data is supposed to be static anyway.