访问Context.Consumer之外的上下文值

时间:2019-11-25 00:37:09

标签: reactjs

我正在尝试访问样式化组件中ThemeContext.Consumer的值。我正在使用盖茨比实现暗模式。

这是ThemeContext.Consumer文件:

import React from 'react'

const defaultState = {
  dark: false,
  toggleDark: () => {},
}
const ThemeContext = React.createContext(defaultState)
// Getting dark mode information from OS!
// You need macOS Mojave + Safari Technology Preview Release 68 to test this currently.
const supportsDarkMode = () =>
  window.matchMedia('(prefers-color-scheme: dark)').matches === true
class ThemeProvider extends React.Component {
  state = {
    dark: false,
  }

  componentDidMount() {
    // Getting dark mode value from localStorage!
    const lsDark = JSON.parse(localStorage.getItem('dark'))
    if (lsDark) {
      this.setState({ dark: lsDark })
    } else if (supportsDarkMode()) {
      this.setState({ dark: true })
    }
  }

  // https://stackoverflow.com/questions/59005886/eslint-prevent-using-this-state-within-a-this-setstate-react-no-access-state-i?stw=2
  toggleDark = () => {
    const dark = !this.state.dark
    localStorage.setItem('dark', JSON.stringify(dark))
    this.setState(({ dark }) => ({ dark: !dark }))
  }

  render() {
    const { children } = this.props
    const { dark } = this.state
    return (
      <ThemeContext.Provider
        value={{
          dark,
          toggleDark: this.toggleDark,
        }}
      >
        {children}
      </ThemeContext.Provider>
    )
  }
}
export default ThemeContext
export { ThemeProvider }

这是我的Header.js file

import React from 'react'
import styled from 'styled-components'

import ThemeContext from '../context/ThemeContext'

class Header extends React.Component {
  render() {
    const currentTheme = this.props.theme

    return (
      <ThemeContext.Consumer>
        {theme => (
          <HeaderWrapper>
            <span
              role="presentation"
              className="dark-switcher"
              onClick={theme.toggleDark}
            >
              {theme.dark ? <span>☀</span> : <span>☾</span>}
            </span>
          </HeaderWrapper>
        )}
      </ThemeContext.Consumer>
    )
  }
}

export default Header

const HeaderWrapper = styled.div`
  background: ${() => (theme.dark ? '#C6D0EB' : '#205284')};
  border-bottom: 1px solid var(--accents-2);
`

我添加了const currentTheme = this.props.theme以便能够全局使用该值。期望能够在我的样式化组件中使用它。

关于如何解决此问题的任何建议?

1 个答案:

答案 0 :(得分:0)

您可能正在寻找contextType属性。它的工作方式如下:

1)向其分配上下文对象;
2)访问this.context上提供的值。

import ThemeContext from '../context/ThemeContext'

class Header extends React.Component {
  // as a public class field
  static contextType = ThemeContext

  render() {
    const { toggleDark, dark } = this.context

    return (
      <HeaderWrapper>
        <span
          role="presentation"
          className="dark-switcher"
          onClick={toggleDark}
        >
          {dark ? <span>☀</span> : <span>☾</span>}
        </span>
      </HeaderWrapper>
    )
  }
}

// or as a property
Header.contextType = ThemeContext

我注意到您正在使用React版本,该版本包含对钩子的支持-如果您愿意,useContext钩子提供了一种利用上下文值的替代方法。