【问题标题】:React.js: How to implement dark/light mode in body toggling with useContext?React.js:如何在使用 useContext 的身体切换中实现暗/亮模式?
【发布时间】:2020-09-19 06:55:52
【问题描述】:

我正在尝试创建一个可以开启 onClick 的背景主题。在 onClick 上它必须改变 react appbody 的背景颜色。我已经成功实现了 useContext,现在它可以切换和更改 Header 组件 中的列表项颜色。如何也将其设置为 body?任何帮助将不胜感激。

这是我的 useContext 颜色组件

import React from 'react'

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

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

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

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>
  )
}

标题组件

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>
  )
}

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    如果您想更改应用程序中的body 标签,您需要修改DOM,您可以将此代码添加到您的 Header.js(或您的上下文中的任何其他文件)文件中:

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

    *** 别忘了导入useEffect

    *** 像下面这样的内联样式比直接修改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>
    

    【讨论】:

    • 非常感谢。它工作正常。但是为什么要在 UseEffect 中定义呢?你能解释一下吗?
    • 我很高兴它帮助了@Greg。我已经在useEffect 中定义了它,以确保它在DOM 中呈现body 后应用更改,您可以从useEffect 中删除它。或者将foreground添加到依赖数组中以改进其功能!
    猜你喜欢
    • 2021-03-05
    • 2020-10-20
    • 2020-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 2020-08-24
    • 2022-01-04
    相关资源
    最近更新 更多