簡體   English   中英

React,使用 localStorage 實現暗光模式

[英]React, implementing Dark-Light-Mode with localStrorage

我正在嘗試使用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)獲得了正確的值,但我無法更改整個應用程序的背景顏色。 有什么想法可以解決這個問題嗎?

您遇到了級聯問題,因為您將主題設置在body上,並嘗試稍后通過App組件更改它。 data-theme添加到body本身或html之前,而不是之后的內容。

在您return之前在App.js中添加這個useEffect將起作用:

useEffect(() => {
  document.documentElement.setAttribute("data-theme", theme);
}, [theme]);

您可以在CodeSandbox上對其進行測試。 這是你的洞App組件:

import './App.css';
import React, {useEffect} 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);
  }
  useEffect(() => {
    document.documentElement.setAttribute("data-theme", theme);
  }, [theme]);
  return (
    <BrowserRouter>
      <div className='App'>
        <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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM