我试图使用use-local-storage
来实现React中的主题转换器。
应用程序组件:
import './App.css';
import React from 'react';
import { Navbar, SearchBar, Header, Main, Chart, Map } from './components';
import { Routes, Route, BrowserRouter } from 'react-router-dom';
import useLocalStorage from 'use-local-storage';
function App() {
// a function that toggles between darkmode and lightmode in css
const defaultDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const [theme, setTheme] = useLocalStorage('theme', defaultDark ? 'dark' : 'light');
const switchTheme = () => {
const newTheme = theme === 'light' ? 'dark' : 'light';
setTheme(newTheme);
}
console.log(theme)
return (
<BrowserRouter>
<div className='App' data-theme={theme} >
<Header />
<SearchBar />
<Navbar switchTheme={switchTheme} />
<Routes>
<Route path="/" element={<Main />} />
<Route path="/map" element={<Map />} />
<Route path="/chart" element={<Chart />} />
</Routes>
</div>
</BrowserRouter>
);
}
export default App;
导航栏组件:
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faMapLocationDot, faChartLine, faHouseUser } from '@fortawesome/free-solid-svg-icons'
import React from 'react'
import { Link } from 'react-router-dom'
const Navbar = ({switchTheme}) => {
return (
<nav className='nav'>
<button onClick={switchTheme}>Toggle</button>
<Link to='/'>
<FontAwesomeIcon icon={faHouseUser} size='4x' color='blue' />
<br></br>
Home
</Link>
<Link to='/map'>
<FontAwesomeIcon icon={faMapLocationDot} size='4x' />
<br></br>
Map</Link>
<Link to='/chart'>
<FontAwesomeIcon icon={faChartLine} size='4x' color='red' />
<br></br>
Chart</Link>
</nav>
)
}
export default Navbar
CSS:
*, *::after, *::before {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/****************** VARIABLES ******************/
:root {
--background-color:coral;
}
[data-theme="light"] {
--background-color:red;
}
[data-theme="dark"] {
--background-color:yellow;
}
body {
background-color:var(--background-color);
font-family: 'Roboto', sans-serif;
font-size: 16px;
color: #333;
line-height: 1.5;
margin: 2vmin;
}
.App {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
/********************** SearchBar **********************/
form {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
max-width: 500px;
margin: 0 auto;
}
form > svg {
margin-left: -20px;
}
input {
font-size:inherit;
border-radius: 1vmin;
border: .5px solid #ccc;
padding: .5rem;
}
input:focus {
border-color: #333;
}
nav {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
padding: 0.5rem;
background-color: yellow;
border-bottom: 1px solid #eaeaea;
width: 10vw;
height: 50vh;
border: 3px dotted purple;
align-self: flex-start;
}
a {
text-decoration: none;
}
/* a:active {
/* do sth with selected Link
} */
我在App.js
中从console.log(theme)
获取了正确的值,但我无法更改整个应用程序的背景色。有什么办法可以解决这个问题吗?
1条答案
按热度按时间kkih6yb81#
当您在
body
上设置主题,并尝试稍后通过App
组件更改它时,您遇到了级联问题。请在body
本身或html
上添加data-theme
,body
在前面,而不是在后面。在
App.js
中return
之前添加useEffect
可以工作:在下面找到完整的示例和CodeSandbox: