Next.js 中未定义本地存储

问题描述 投票:0回答:5

我正在尝试将应用程序从 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')
        }
    }
reactjs next.js local-storage
5个回答
3
投票

当您的应用程序在服务器上呈现时,那里没有

browser
API。 您需要做的是仅当应用程序在浏览器中呈现时才访问
localStorage
。您可以通过等待组件安装然后访问
localStorage

来完成此操作
function MyComponent(){
  // this runs only in the browser
  useEffect(()=>{
  // access local storage here
  },[])
}

2
投票

我似乎通过将逻辑从 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)
            }
        

0
投票

您可以使用此代码

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')
        }
  }

0
投票

您可以将其声明为虚拟的或空白的内部

useState
。安装应用程序后,使用
useEffect
进行设置。

请注意,您现有的 setAuthTokens 函数将在 loginUser 函数内正常工作,无需任何更改。


-1
投票

useState
内部,您可以在访问本地存储之前检查window是否未定义。你可以做这样的事情

let [authTokens, setAuthTokens] = useState(
  () => typeof window !== "undefined" 
    ? localStorage.getItem('authTokens') 
        ? JSON.parse(localStorage.getItem('authTokens')) 
        : null)
© www.soinside.com 2019 - 2024. All rights reserved.