Kooki Kodes
Weird solid start behavior
I'm not sure I understand how solid router actions work. The following code is causing a hard full page refresh.
I'm also noticing none of my reactivity is work 😅
// src/hooks/createUserTheme.ts
import { createAsync, cache, action, json, reload } from "@solidjs/router";
import { createEffect, onCleanup } from "solid-js";
import { getCookie, setCookie } from "vinxi/http";
type Theme = "light" | "dark";
const DEFAULT: Theme = "dark",
THEME_KEY = "user-theme";
export const getThemeCookie = () => (getCookie(THEME_KEY) || "dark") as Theme;
export const getTheme = cache(async () => {
"use server";
return getThemeCookie();
}, THEME_KEY);
export const updateTheme = action(async (formData: FormData) => {
"use server";
const theme = formData.get(THEME_KEY)?.toString() || DEFAULT;
setCookie(THEME_KEY, theme);
return reload({ status: 200, revalidate: [THEME_KEY] });
}, THEME_KEY);
export const createUserTheme = () => {
const theme = createAsync(() => getTheme());
createEffect(() => {
const t = theme();
if (!t) return;
document.documentElement.classList.add(t);
onCleanup(() => {
document.documentElement.classList.remove(t);
});
});
return [theme, updateTheme] as const;
};
// src/components/ThemeToggle.tsx
import { createUserTheme, getTheme } from "~/hooks/createUserTheme";
export default function ThemeToggle() {
const [theme, updateTheme] = createUserTheme();
return (
<form action={updateTheme} method="post">
<input
type="hidden"
name={getTheme.key}
value={theme() === "light" ? "dark" : "light"}
/>
<button class="dark:bg-white bg-black text-white dark:text-black py-1.5 px-3 rounded-xl font-monument-regular ">
Toggle Theme
</button>
</form>
);
}
// src/hooks/createUserTheme.ts
import { createAsync, cache, action, json, reload } from "@solidjs/router";
import { createEffect, onCleanup } from "solid-js";
import { getCookie, setCookie } from "vinxi/http";
type Theme = "light" | "dark";
const DEFAULT: Theme = "dark",
THEME_KEY = "user-theme";
export const getThemeCookie = () => (getCookie(THEME_KEY) || "dark") as Theme;
export const getTheme = cache(async () => {
"use server";
return getThemeCookie();
}, THEME_KEY);
export const updateTheme = action(async (formData: FormData) => {
"use server";
const theme = formData.get(THEME_KEY)?.toString() || DEFAULT;
setCookie(THEME_KEY, theme);
return reload({ status: 200, revalidate: [THEME_KEY] });
}, THEME_KEY);
export const createUserTheme = () => {
const theme = createAsync(() => getTheme());
createEffect(() => {
const t = theme();
if (!t) return;
document.documentElement.classList.add(t);
onCleanup(() => {
document.documentElement.classList.remove(t);
});
});
return [theme, updateTheme] as const;
};
// src/components/ThemeToggle.tsx
import { createUserTheme, getTheme } from "~/hooks/createUserTheme";
export default function ThemeToggle() {
const [theme, updateTheme] = createUserTheme();
return (
<form action={updateTheme} method="post">
<input
type="hidden"
name={getTheme.key}
value={theme() === "light" ? "dark" : "light"}
/>
<button class="dark:bg-white bg-black text-white dark:text-black py-1.5 px-3 rounded-xl font-monument-regular ">
Toggle Theme
</button>
</form>
);
}
6 replies