【问题标题】:localstorage not defined in Next.js本地存储未在 Next.js 中定义
【发布时间】:2022-01-05 13:27:00
【问题描述】:

我试图将应用程序从 React 移动到 Next

在 React 中,这段代码没有错误

let [authTokens, setAuthTokens] = useState(() => localStorage.getItem('authTokens') ? JSON.parse(localStorage.getItem('authTokens')) : null)

let [user, setUser] = useState(()=> localStorage.getItem('authTokens') ? jwt_decode(localStorage.getItem('authTokens')) : null)

但是当我尝试在 Next 中使用它时,我得到了错误

我假设是因为 Next 首先在服务器端渲染,而服务器端没有本地存储。

这是设置本地存储的函数。

let loginUser = async (e) => {
        e.preventDefault();
        let response = await fetch('http://127.0.0.1:8000/api/token/', {
            method:'POST',
            headers:{
                'Content-Type': 'application/json'
            },
            body:JSON.stringify({'email':e.target.username.value, 'password':e.target.password.value})
        })
        let data = await response.json()
        console.log(data)
        console.log(data.access)
        if(response.status == 200) {
            setAuthTokens(data)
            setUser(jwt_decode(data.access))
            localStorage.setItem('authTokens', JSON.stringify(data))
            router.push('/')
        } else {
            alert('something went wrong')
        }
    }

【问题讨论】:

  • 你在哪里调用 loginUser 方法,是在客户端还是服务器端。
  • @RajneeshChaurasia 它的客户端,由表单上的提交按钮触发
  • 问题发生在第一次渲染还是提交表单之后???
  • @devAR Next.js pre-renders every page 在服务器上,这意味着像 localStorage 这样的 Web API 不可用。您必须在 useEffect 中移动任何仅限客户端的代码。

标签: reactjs next.js local-storage


【解决方案1】:

您可以使用此代码

if (typeof window !== "undefined") {
   if(response.status == 200) {
            setAuthTokens(data)
            setUser(jwt_decode(data.access))
            localStorage.setItem('authTokens', JSON.stringify(data))
            router.push('/')
        } else {
            alert('something went wrong')
        }
  }

【讨论】:

    【解决方案2】:

    当您的应用程序在服务器上呈现时,那里没有browser API。 您需要做的是仅在应用程序在浏览器中呈现时访问localStorage。你可以通过等待组件被挂载然后访问localStorage来做到这一点

    function MyComponent(){
      // this runs only in the browser
      useEffect(()=>{
      // access local storage here
      },[])
    }
    

    【讨论】:

    • 我是否将 useSates 放在 useEffect 中(我认为你不能),因为在错误中,它指向 useStates。更新图片
    • 你不能把localStorage放在useState中(useState运行时没有localStorage
    【解决方案3】:

    我似乎已经通过将逻辑从 useState 中移到 useEffect 中来修复它

    而不是拥有

    let [authTokens, setAuthTokens] = useState(() => localStorage.getItem('authTokens') ? JSON.parse(localStorage.getItem('authTokens')) : null)
    
    let [user, setUser] = useState(()=> localStorage.getItem('authTokens') ? jwt_decode(localStorage.getItem('authTokens')) : null)
    

    我像这样移动了 useEffect 中的逻辑

    let [authTokens, setAuthTokens] = useState(null)
    let [user, setUser] = useState(null)
    
        useEffect(() => {
            
                if(localStorage.getItem('authTokens')) {
                    setAuthTokens(JSON.parse(localStorage.getItem('authTokens')))
                    setUser(jwt_decode(localStorage.getItem('authTokens')))
                } else {
                    setAuthTokens(null)
                    setUser(null)
                }
            
    

    【讨论】:

      猜你喜欢
      • 2020-02-18
      • 1970-01-01
      • 1970-01-01
      • 2018-03-10
      • 1970-01-01
      • 2017-02-07
      • 1970-01-01
      • 1970-01-01
      • 2021-09-12
      相关资源
      最近更新 更多