NextJs에 대한 사용자 지정 후크가 있어야 합니다.

useLocalStorage 사용자 지정 후크



localstorage에서 사용자 테마와 토큰을 저장하고 검색하는 데 도움이 되도록 함께 묶었습니다.



a react vite app 에서 작업 중이었고 이를 Next Jsthe ported next js app로 포팅해야 했고 localStorage가 Nextjs에서 약간 다르게 작동한다는 것을 매우 빨리 발견했습니다. 다음과 같은 사용자 지정 후크가 생성된 토끼 구멍 아래로



import { useState,useEffect,useReducer } from 'react';
import { Viewer } from './../types/usertypes';

interface State{
token:string|null
theme:string|null
mainuser?:Viewer
error?:string
}


export const useLocalStorge=()=>{

const [loading, setLoading] = useState(true);
const [ state,dispatch] = useReducer(generalReducer,undefined);
useEffect(() => {
 const gen = window.localStorage.general; 
 if(gen){
  dispatch({ type: "INIT", payload: JSON.parse(gen) });
 }
 setLoading(false)
}, [])


useEffect(() => {
  const colorTheme = state?.theme === "dark" ? "light" : "dark";
  const root = window.document.documentElement;
    // console.log("colorTheme ==== ", colorTheme);
  root.classList.remove(colorTheme);
  // console.log("theme reset to ==== ",state?.theme)
  if(state?.theme){
    root.classList.add(state?.theme);
  }

}, [state?.theme]);



useEffect(() => {
if(state)
window.localStorage.setItem("general",JSON.stringify(state))
}, [state])

return {loading ,state ,dispatch}
}






function generalReducer(state:State, action:any) {
switch (action.type) {

  case "INIT":
    return action.payload;
  case "THEME":
    return {...state,theme:action.payload}
  case "TOKEN":
    return {...state,token:action.payload}  
  case "ERROR":
    return {...state,error:action.payload} 

  default:
    return state;
}
}




그리고 당신은 그것을 소비

import "../styles/globals.css";
import type { AppProps } from "next/app";
import { ReactQueryDevtools } from "react-query/devtools";
import { QueryClient, QueryClientProvider } from "react-query";
import { Layout } from "../components/Layout";
import { useLocalStorge } from "./../utils/hooks/useLocalStorge";
import GlobalContext from "../utils/context/GlobalsContext";

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      refetchOnWindowFocus: false,
      refetchOnMount: false,
      refetchOnReconnect: false,
      retry: false,
      staleTime: 5 * 60 * 1000,
    },
  },
});

function MyApp({ Component, pageProps }: AppProps) {
  const local = useLocalStorge();
  // console.log("local state ==== ",local?.state)

  // console.log("initial value in local storage ==== ", value);

  return (
    <QueryClientProvider client={queryClient}>
      <GlobalContext.Provider
        value={{ value: local?.state, updateValue: local?.dispatch }}
      >
        <Layout local={local}>
          <Component {...pageProps} />
          <ReactQueryDevtools />
        </Layout>
      </GlobalContext.Provider>
    </QueryClientProvider>
  );
}

export default MyApp;




cotext는 선택 사항이지만 다음과 같이 보입니다.

import React, { Dispatch } from "react";
import { Viewer } from './../types/usertypes';

export interface Value {
  token: string | null;
  theme:string
  error?: string;
  mainuser?:Viewer
}
interface Type {
  value: Value;
  updateValue:Dispatch<any>
}

const init_data: Type = {
  value:{token:null,theme:"light"},
  updateValue: (any) => {},
};

const GlobalContext = React.createContext(init_data);
export default GlobalContext;



final project looks like

좋은 웹페이지 즐겨찾기