CodingWithJamal
CodingWithJamal3mo ago

Need a little react help

Hello family, its been a while. So for my site I wanted to save a simple count of users visited. I wrote this code:
"use client";

import { useMutation } from "convex/react";
import { useEffect } from "react";
import { api } from "../../convex/_generated/api";
import useLocalStorage from "@/hooks/useLocalStorage";

const GlobalStatsTracker = () => {
const [viewCounted, setViewCounted] = useLocalStorage<"no" | "yes">(
"view_counted",
{
defaultValue: "no",
}
);
const updateGlobalStats = useMutation(api.global_kv.updateGlobalStats);

useEffect(() => {
console.table({
viewCounted,
"window.location.host.includes('localhost')":
window.location.host.includes("localhost"),
"typeof window === 'undefined'": typeof window === "undefined",
});

if (typeof window === "undefined") return;
if (viewCounted === "yes") return;
if (process.env.NODE_ENV === "development") return;

updateGlobalStats({ total_users_visited: true })
.then(() => {
setViewCounted("yes");
})
.catch(console.error);
}, [viewCounted]);

return null;
};

export default GlobalStatsTracker;
"use client";

import { useMutation } from "convex/react";
import { useEffect } from "react";
import { api } from "../../convex/_generated/api";
import useLocalStorage from "@/hooks/useLocalStorage";

const GlobalStatsTracker = () => {
const [viewCounted, setViewCounted] = useLocalStorage<"no" | "yes">(
"view_counted",
{
defaultValue: "no",
}
);
const updateGlobalStats = useMutation(api.global_kv.updateGlobalStats);

useEffect(() => {
console.table({
viewCounted,
"window.location.host.includes('localhost')":
window.location.host.includes("localhost"),
"typeof window === 'undefined'": typeof window === "undefined",
});

if (typeof window === "undefined") return;
if (viewCounted === "yes") return;
if (process.env.NODE_ENV === "development") return;

updateGlobalStats({ total_users_visited: true })
.then(() => {
setViewCounted("yes");
})
.catch(console.error);
}, [viewCounted]);

return null;
};

export default GlobalStatsTracker;
which works fine but for some reason every page refresh the updateGlobalStats is called even when the view has been set in local storage? This should not happen
viewCounted 'yes'
window.location.host.includes('localhost') true
typeof window === 'undefined' false
viewCounted 'yes'
window.location.host.includes('localhost') true
typeof window === 'undefined' false
This is the console output.
10 Replies
Convex Bot
Convex Bot3mo ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
CodingWithJamal
CodingWithJamalOP3mo ago
If anyone has implemented something like this in convex themselfs let me know please!
jamalsoueidan
jamalsoueidan3mo ago
Clear your console log, and refresh the page...and see what you get on the first run...
Hmza
Hmza3mo ago
const [viewCounted, setViewCounted] = useLocalStorage<"no" | "yes">(
"view_counted",
{
defaultValue: "no",
}
);
const [viewCounted, setViewCounted] = useLocalStorage<"no" | "yes">(
"view_counted",
{
defaultValue: "no",
}
);
useLocalStorage might not being read correctly because of the extra wrap defaultValue try this to make sure value is read from localstorage correctly on component mount: const [viewCounted, setViewCounted] = useLocalStorage<"no" | "yes">("view_counted", "no"); @CodingWithJamal
CodingWithJamal
CodingWithJamalOP3mo ago
No description
CodingWithJamal
CodingWithJamalOP3mo ago
It seems to default to no at first even though in local storage its "true" right now
jamalsoueidan
jamalsoueidan3mo ago
As @Hmza mentioned the initalie value may be incorrect, useLocalStorage('view_counted', 'yes');
CodingWithJamal
CodingWithJamalOP3mo ago
export default function useLocalStorageState<T>(
key: string,
options?: LocalStorageOptions<T>,
): LocalStorageState<T>;

export type LocalStorageOptions<T> = {
defaultValue?: T | (() => T);
storageSync?: boolean;
serializer?: {
stringify: (value: unknown) => string;
parse: (value: string) => unknown;
};
};
export default function useLocalStorageState<T>(
key: string,
options?: LocalStorageOptions<T>,
): LocalStorageState<T>;

export type LocalStorageOptions<T> = {
defaultValue?: T | (() => T);
storageSync?: boolean;
serializer?: {
stringify: (value: unknown) => string;
parse: (value: string) => unknown;
};
};
the api for default value is not the problem
Hmza
Hmza3mo ago
It seems like the issue might be with how the initial value is being read from local storage.double check if the defaultValue option in useLocalStorage is being set correctly, and ensure that it aligns with the value stored in local storage. You could also log the value right after calling useLocalStorage to see what it's retrieving on the first render.
CodingWithJamal
CodingWithJamalOP3mo ago
okay i will check

Did you find this page helpful?