CreateLocalStorage hook problem with reactivity

I'm trying to make a custom hook that exposes a signal and uses the LocalStore of the browser.
import { Signal, createSignal } from "solid-js";

function createStoredSignal<T>(key: string, defaultValue: T, storage = localStorage): Signal<T> {
const initialValue = storage.getItem(key)
? (JSON.parse(storage.getItem(key)) as T)
: defaultValue;

const [value, setValue] = createSignal<T>(initialValue);

const setValueAndStore = ((arg) => {
const v = setValue(arg);
storage.setItem(key, JSON.stringify(v));
return v;
}) as typeof setValue;

return [value, setValueAndStore];
}
export default createStoredSignal;
import { Signal, createSignal } from "solid-js";

function createStoredSignal<T>(key: string, defaultValue: T, storage = localStorage): Signal<T> {
const initialValue = storage.getItem(key)
? (JSON.parse(storage.getItem(key)) as T)
: defaultValue;

const [value, setValue] = createSignal<T>(initialValue);

const setValueAndStore = ((arg) => {
const v = setValue(arg);
storage.setItem(key, JSON.stringify(v));
return v;
}) as typeof setValue;

return [value, setValueAndStore];
}
export default createStoredSignal;
the problem is this don't seem to work with reactivity.
9 Replies
Alex Lohr
Alex Lohr14mo ago
Are there any erorrs in the console?
akerbeltz
akerbeltz14mo ago
nop, it's strange..
Alex Lohr
Alex Lohr14mo ago
Can you show where you used the reactivity?
akerbeltz
akerbeltz14mo ago
hmm i lost that files cause i implemented the functionality in another way but was something like
Alex Lohr
Alex Lohr14mo ago
Was it maybe an effect outside of a reactive root?
akerbeltz
akerbeltz14mo ago
I have some code that works but something like this don't work when the button redirection to a new page, it was strange could be something like this but with navigations of solid-router to new pages when clicking the buttons and showing the name and id in another component but to simplify something like this
import { render } from "solid-js/web";
import { createContext, createSignal } from "solid-js";
function createStoredSignal<T>(
key: string,
defaultValue: T,
storage = localStorage
): Signal<T> {
const initialValue = storage.getItem(key)
? (JSON.parse(storage.getItem(key)) as T)
: defaultValue;

const [value, setValue] = createSignal<T>(initialValue);

const setValueAndStore = ((arg) => {
const v = setValue(arg);
storage.setItem(key, JSON.stringify(v));
return v;
}) as typeof setValue;

return [value, setValueAndStore];
}

function App() {
const [name, setName] = createStoredSignal("name", "");
const [id, setId] = createStoredSignal("id", "0");

return (
<>
<button
onClick={() => {
setName("Aker"), setId("1");
}}
>
change name to Aker
</button>
<button
onClick={() => {
setName("Beltz"), setId("2");
}}
>
change name to Beltz
</button>
<div>{name() + " " + id()}</div>
</>
);
}

render(() => <App />, document.getElementById("app"));
import { render } from "solid-js/web";
import { createContext, createSignal } from "solid-js";
function createStoredSignal<T>(
key: string,
defaultValue: T,
storage = localStorage
): Signal<T> {
const initialValue = storage.getItem(key)
? (JSON.parse(storage.getItem(key)) as T)
: defaultValue;

const [value, setValue] = createSignal<T>(initialValue);

const setValueAndStore = ((arg) => {
const v = setValue(arg);
storage.setItem(key, JSON.stringify(v));
return v;
}) as typeof setValue;

return [value, setValueAndStore];
}

function App() {
const [name, setName] = createStoredSignal("name", "");
const [id, setId] = createStoredSignal("id", "0");

return (
<>
<button
onClick={() => {
setName("Aker"), setId("1");
}}
>
change name to Aker
</button>
<button
onClick={() => {
setName("Beltz"), setId("2");
}}
>
change name to Beltz
</button>
<div>{name() + " " + id()}</div>
</>
);
}

render(() => <App />, document.getElementById("app"));
Alex Lohr
Alex Lohr14mo ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Alex Lohr
Alex Lohr14mo ago
So I assume there's a different issue.
akerbeltz
akerbeltz14mo ago
yep, i think it can be something related to router or something like that The app i'm doing is very similar but: There's an appbar component that always will show the name and id if there's one in the localStorage. There's a page to select name (that selects the id of that name) , here there are several items to select a name And when selecting a name it redirects to a subpage of user configuration When i have time I'll try to replicate the app (very simple) but with all the components and with solid-router The thing that fails in the app is that the appbar component mentioned before don't change when selecting one item in the select names page In the app that I'm doing the id don't really need to be shown in the appbar so I created a version of the hook that I think is a singleton this is the code that I have now working only for names the id I get directly from the localStorage.
import { createSignal } from "solid-js";

const initialValue = window.localStorage.getItem("name")
? JSON.parse(window.localStorage.getItem("name"))
: "";

const [value, setValue] = createSignal(initialValue);

function useStoredSignal(key) {
const setValueAndStore = (arg) => {
const v = setValue(arg);
window.localStorage.setItem(key, JSON.stringify(v));
};

return [value, setValueAndStore];
}
export default useStoredSignal;
import { createSignal } from "solid-js";

const initialValue = window.localStorage.getItem("name")
? JSON.parse(window.localStorage.getItem("name"))
: "";

const [value, setValue] = createSignal(initialValue);

function useStoredSignal(key) {
const setValueAndStore = (arg) => {
const v = setValue(arg);
window.localStorage.setItem(key, JSON.stringify(v));
};

return [value, setValueAndStore];
}
export default useStoredSignal;