Home > Back-end >  Can't access localStorage in my own Hook with Next
Can't access localStorage in my own Hook with Next

Time:02-21

I want to make a hook in which the User credentials are stored (authToken etc.). I want to save the user to the localStorage so I made a custom hook which does that. Unfortunately, my code doesn't compile because window is not defined. Im using the next framework so I guess it's because node doesn't have the window object. How can I make it compile? I only want to use the hook on client side, so the window object should always be available...

My Hook:

    interface User {
    username: string;
    userId: string;
    authToken: string;
    refreshToken: string;
    language: Language;
}

export default function useUser(): [User | null, (user: User | null) => void] {
    const [user, setUser] = useState<User | null>(getLocalStorage('user'));

    if (window?.localStorage) {
        window.addEventListener('storage', () =>
            setUser(getLocalStorage('user'))
        );
    }

    return [user, user => setLocalStorage('user', user)];
}

function getLocalStorage<T>(key: string): T | null {
    if (window?.localStorage) {
        const storage = window.localStorage.getItem(key);
        return storage && JSON.parse(storage);
    } else {
        return null;
    }
}

function setLocalStorage(key: string, value?: any): void {
    if (value) {
        window.localStorage.setItem(key, JSON.stringify(value));
    } else {
        window.localStorage.removeItem(key);
    }
}

CodePudding user response:

u need to understand how SSR works, NextJS will build React app into static file, which mean during the build time, the code run within server-side, it's server machine, not user's browser, that's why window object is not define.

Instead, u consider solution as below

  • load data from localStorage within componentDidMount or useEffect.

  • If you are using NextJS, you can also customize App (docs) and combine with React Context on component mount to share state in whole application.

CodePudding user response:

I think you can use localStorage without putting window before, using React

For example, window.localStorage.setItem(key, JSON.stringify(value)); becomes localStorage.setItem(key, JSON.stringify(value));

  • Related