我正在尝试将应用程序从 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')
}
}
当您的应用程序在服务器上呈现时,那里没有
browser
API。
您需要做的是仅当应用程序在浏览器中呈现时才访问 localStorage
。您可以通过等待组件安装然后访问 localStorage
来完成此操作
function MyComponent(){
// this runs only in the browser
useEffect(()=>{
// access local storage here
},[])
}
我似乎通过将逻辑从 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)
}
您可以使用此代码
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')
}
}
您可以将其声明为虚拟的或空白的内部
useState
。安装应用程序后,使用 useEffect
进行设置。
请注意,您现有的 setAuthTokens 函数将在 loginUser 函数内正常工作,无需任何更改。
在
useState
内部,您可以在访问本地存储之前检查window是否未定义。你可以做这样的事情
let [authTokens, setAuthTokens] = useState(
() => typeof window !== "undefined"
? localStorage.getItem('authTokens')
? JSON.parse(localStorage.getItem('authTokens'))
: null)