Next.js中未定义本地存储

zqdjd7g9  于 2023-02-22  发布在  其他
关注(0)|答案(4)|浏览(189)

我正在尝试将应用程序从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')
        }
    }
3mpgtkmj

3mpgtkmj1#

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

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

pbossiut2#

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

iaqfqrcu3#

您可以使用以下代码

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

7gyucuyw4#

在useState中,你可以在访问本地存储之前检查window是否未定义。
让[验证令牌,设置验证令牌]=使用状态(()=〉窗口类型!=="未定义"?本地存储.获取项("验证令牌")?JSON.解析(本地存储.获取项("验证令牌")):无效)

相关问题