【发布时间】:2021-07-05 01:35:01
【问题描述】:
我正在尝试根据存储在本地存储中的主题键在深色和浅色之间切换主题。我有一个功能可以在单击时更改本地存储中的键值。但是,单击不会呈现组件,用户必须刷新页面才能看到更新的主题。
这里是 App.js 组件,检查本地存储,如果本地存储为 null,则设置默认主题:
import React from 'react';
const App = () => {
return (
<Router>
<div className=
{
window.localStorage.getItem('theme') === null ?
window.localStorage.setItem('theme','theme-light'):
window.localStorage.getItem('theme')
}>
<Switch>
<Route exact path='/'> <LandingPage/> </Route>
<Route exact path='/register'> <RegisterPage/> </Route>
<Route exact path='/login'> <LoginPage/> </Route>
</Switch>
</div>
</Router>
);
}
export default App;
这里的函数包含一个在本地存储中设置新主题的函数,onclick键值在本地存储中确实发生了变化,但是页面不会重新渲染,需要用户手动刷新页面从本地存储中获取更新的主题。
我希望主题在点击时打开。
import React,{useState, useEffect} from 'react'
import {RiMoonLine} from 'react-icons/ri'
import {FiSun} from 'react-icons/fi'
const UserProfilePromoter = () =>{
const [user, setUser] = useState({})
const items = { ...localStorage }
const localUser = JSON.parse(window.localStorage.getItem('user'))
useEffect(()=>{
if(localUser){
const userId = localUser.id
const userFullName = `${localUser.firstname} ${localUser.lastname}`
const username = localUser.username
const avatar = localUser.avatar
setUser({
...user,
id: userId,
name: userFullName,
username: username,
avatar: avatar,
theme: items.theme
})
}
},[])
const onThemeChange = (e) => {
let currentTheme = window.localStorage.getItem('theme')
console.log(currentTheme)
if(currentTheme === 'theme-light') {
window.localStorage.setItem('theme', 'theme-dark')
setUser({
...user,
theme: 'theme-dark'
})
} else {
window.localStorage.setItem('theme', 'theme-light')
setUser({
...user,
theme: 'theme-light'
})
}
}
return(
<>
{
localUser &&
<div className="profilePrompterContainer">
<div className="ProfilePrompterAvatarWrapper" role="button">
<div className="ProfilePrompterAvatar ProfilePrompterWrapper">
<img src={user.avatar}
className="profilePrompterUserAvatar" alt={`sosums_user_${user.name}`}
/>
</div>
</div>
<div className="ProfilePrompterNameTag" role="button" >
<div className="userFullNameContainer">
<div className="userFullNameText">{user.name}</div>
</div>
<div className="profilePrompterUsernameText size12">
{!user.username ? <div className='setUserNameText'> @Set Username </div>: user.username}
</div>
</div>
<div className="ProfilePrompterBtnGroup" onClick={onThemeChange}>
<button type="button" className="iconBtn">
<div className="iconContentWrapper">
<span className='iconContent'>
{
window.localStorage.getItem('theme')=== 'theme-light' ? <RiMoonLine/>:
<FiSun/>
}
</span>
</div>
</button>
</div>
</div>
}
{
!localUser && <div className="noLocalUser"> </div>
}
</>
)
}
export default UserProfilePromoter
【问题讨论】:
-
useEffect 不监听本地存储的变化
-
要重新渲染一个 React 组件,你只需要更新一个状态,但这次不同,要重新加载应用程序,你必须使用
window.location.reload()强制重新加载,这在用户刷新时是一样的该页面,您将需要找到使用 reload() 的位置
标签: javascript reactjs local-storage