简体   繁体   English

React.js:如何在使用 useContext 切换身体时实现暗/亮模式?

[英]React.js: How to implement dark/light mode in body toggling with useContext?

I am trying to create a background theme which will switch on onClick .我正在尝试创建一个背景主题,它将打开onClick On onClick it must change the background color of body in react app .onClick 上,它必须更改react appbody的背景颜色。 I've managed to implement useContext , and now it toggles and changes the list items color in Header component .我已经设法实现了useContext ,现在它可以切换和更改Header 组件中的列表项颜色。 How to set it to body as well?如何将它设置为身体 Any help will be appreciated.任何帮助将不胜感激。

Here is my useContext color component这是我的 useContext 颜色组件

import React from 'react'

export const themes = {
  light: {
    foreground: '#ffffff',
  },
  blue: {
    foreground: 'blue',
  },
}

export default React.createContext({
  theme: themes.light,
  switchTheme: () => {},
})

onClick Button component onClick 按钮组件

import React, { useContext } from 'react'
import ThemeContext from './context'

import './ThemedButton.scss'

const ThemedButton = () => {
  const { switchTheme } = useContext(ThemeContext)

  return (
    <>
      <button className="btn" onClick={switchTheme}>
        Switch
      </button>
    </>
  )
}

export default ThemedButton 

App.js应用程序.js

import React, { useState } from 'react'

import SearchBar from './components/SearchBar';
import useCountries from './Hooks/useCountries';
import MainTable from './components/MainTable';
import ThemeButton from './useContext/ThemedButton';
import ThemeContext from './useContext/context';

import { searchProps } from './types';
import { themes } from './useContext/context';
import Routes from './Routes';


import './App.scss'

export default function App() {
  const [search, setSearch] = useState('')
  const [data] = useCountries(search)
  const [context, setContext] = useState({
    theme: themes.light,
    switchTheme: () => {
      setContext((current) => ({
        ...current,
        theme: current.theme === themes.light ? themes.blue : themes.light,
      }))
    },
  })

  const handleChange: React.ReactEventHandler<HTMLInputElement> = (e): void => {
    setSearch(e.currentTarget.value)
  }

  return (
    <div className="App">
      <SearchBar handleChange={handleChange} search={search as searchProps} />

      <ThemeContext.Provider value={context}>
        <ThemeButton />
        <MainTable countries={data} />
      </ThemeContext.Provider>

      <Routes />
    </div>
  )
}

Header component标题组件

import React, { useContext } from 'react'

import ThemeContext from '../../useContext/context'


import './Header.scss'

export default function Header() {
  const { theme } = useContext(ThemeContext)

  return (
    <div className="header">
      <ul className="HeadtableRow" style={{ color: theme.foreground }}> // here it's set to change list items color
        <li>Flag</li>
        <li>Name</li>
        <li>Language</li>
        <li>Population</li>
        <li>Region</li>

      </ul>
    </div>
  )
}

If you want to change your body tag in your application you need to modify DOM and you can add this code to your Header.js (or any other file under your context) file:如果您想更改应用程序中的body标记,则需要修改DOM并且可以将此代码添加到 Header.js(或上下文中的任何其他文件)文件中:

useEffect(() => {
    const body = document.getElementsByTagName("body");
    body[0].style.backgroundColor = theme.foreground
  },[])

*** Don't forget to import useEffect *** 不要忘记导入useEffect

*** Inline style like below is a better approach than modifying DOM directly *** 像下面这样的内联样式是比直接修改DOM更好的方法

<div className="App" style={{backgroundColor: context.theme.foreground}}> 
     //For under context files just use theme.foreground
      <SearchBar handleChange={handleChange} search={search as searchProps} />
      <ThemeContext.Provider value={context}>
        <ThemeButton />
        <MainTable countries={data} />
      </ThemeContext.Provider>

      <Routes />
    </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM