“update state from context return error ‘setState is not a function'”

huangapple go评论58阅读模式
英文:

update state from context return error 'setState is not a function'

问题

Description

我正在使用React.JS中的useContext中的上下文创建一个暗/亮模式功能,但我遇到了一个问题。我对在React.js中使用useContext还很新,所以我请求帮助找到问题。

Problem

当我设置主题时,它返回错误。

Code

ModeProvider.js

import React, { useState } from "react"

export const ModeContext = React.createContext([])

const ModeProvider = ({ children }) => {
  const [darkMode, setDarkMode] = useState(true)
  return (
    <ModeContext.Provider value={[darkMode, setDarkMode]}>
      {children}
    </ModeContext.Provider>
  )
}

export default ModeProvider

ModeButton.js (作为组件)

import React from "react"
import DayIcon from "images/daymode.svg"
import NightIcon from "images/nightmode.svg"
import { ImgButton } from "./ModeButton.styles"

const ModeButton = ({ darkMode, setDarkMode }) => (
  <ImgButton
    src={darkMode ? NightIcon : DayIcon}
    alt="mode"
    onClick={() => setDarkMode(prevState => !prevState)}
  />
)

export default ModeButton

Header.js

import React, { useState, useContext } from 'react'
import { Link } from 'gatsby'
import useConfigQuery from '../../hooks/useConfigQuery'
import { Wrapper, Logo } from './Header.styles'
import Menu from 'components/Menu'
import Hamburger from 'components/Hamburger'
import MobileMenu from 'components/MobileMenu'
import ModeButton from "components/ModeButton"
import { ModeContext } from '../../context/ModeProvider'

const Header = ({ siteTitle = "" }) => {
  const [darkMode, setDarkMode] = useContext(ModeContext);
  const [menuOpen, setMenuOpen] = useState(false);
  const siteConfig = useConfigQuery()

  return (
    <Wrapper>
        <Hamburger menuOpen={menuOpen} setMenuOpen={setMenuOpen}/>
        <MobileMenu menuOpen={menuOpen} items={siteConfig.menu}/>
        <Menu items={siteConfig.menu}/>
        <Link to="/">
            <Logo src={siteConfig.logo.publicURL} alt={siteTitle}/>
        </Link>
        <ModeButton darkMode={darkMode} setDarkMode={setDarkMode} />
    </Wrapper>
  )
}

export default Header;

Layout.js

import Header from 'components/Header'
import { ModeContext } from 'context/ModeProvider'

const Layout = ({ children }) => {
  const [darkMode] = useContext(ModeContext);
  const data = useMetaDataQuery();

  console.log(data)

  return (
    <ThemeProvider theme={darkMode ? darkTheme : lightTheme}>
        <GlobalStyles/>
        <Header siteTitle={data.title}/>
        {children}
    </ThemeProvider>
  )
}

Question

如何修复更新状态代码,以便解决错误? 任何帮助都将不胜感激,谢谢!

英文:

Description

I am creating a dark/light mode feature using context in useContext in React.JS, but I am encountering a problem. I am new to using useContext in react.js, so I am asking for help to find the problem.

Problem

When i set theme, it returns error.

“update state from context return error ‘setState is not a function'”

Code

ModeProvider.js

import React, { useState } from &quot;react&quot;

export const ModeContext = React.createContext([])

const ModeProvider = ({ children }) =&gt; {
  const [darkMode, setDarkMode] = useState(true)
  return (
    &lt;ModeContext.Provider value={[darkMode, setDarkMode]}&gt;
      {children}
    &lt;/ModeContext.Provider&gt;
  )
}

export default ModeProvider

ModeButton.js (as component)

import React from &quot;react&quot;
import DayIcon from &quot;images/daymode.svg&quot;
import NightIcon from &quot;images/nightmode.svg&quot;
import { ImgButton } from &quot;./ModeButton.styles&quot;

const ModeButton = ({ darkMode, setDarkMode }) =&gt; (
  &lt;ImgButton
    src={darkMode ? NightIcon : DayIcon}
    alt=&quot;mode&quot;
    onClick={() =&gt; setDarkMode(prevState =&gt; !prevState)}
  /&gt;
)

export default ModeButton

Header.js

import React, { useState, useContext } from &#39;react&#39;
import { Link } from &#39;gatsby&#39;
import useConfigQuery from &#39;../../hooks/useConfigQuery&#39;
import { Wrapper, Logo } from &#39;./Header.styles&#39;
import Menu from &#39;components/Menu&#39;
import Hamburger from &#39;components/Hamburger&#39;
import MobileMenu from &#39;components/MobileMenu&#39;
import ModeButton from &quot;components/ModeButton&quot;
import { ModeContext } from &#39;../../context/ModeProvider&#39;

const Header = ({ siteTitle = &quot;&quot; }) =&gt; {
  const [darkMode, setDarkMode] = useContext(ModeContext);
  const [menuOpen, setMenuOpen] = useState(false);
  const siteConfig = useConfigQuery()

  return (
    &lt;Wrapper&gt;
        &lt;Hamburger menuOpen={menuOpen} setMenuOpen={setMenuOpen}/&gt;
        &lt;MobileMenu menuOpen={menuOpen} items={siteConfig.menu}/&gt;
        &lt;Menu items={siteConfig.menu}/&gt;
        &lt;Link to=&quot;/&quot;&gt;
            &lt;Logo src={siteConfig.logo.publicURL} alt={siteTitle}/&gt;
        &lt;/Link&gt;
        &lt;ModeButton darkMode={darkMode} setDarkMode={setDarkMode} /&gt;
    &lt;/Wrapper&gt;
  )
}

export default Header;

Layout.js

import Header from &#39;components/Header&#39;
import { ModeContext } from &#39;context/ModeProvider&#39;

const Layout = ({ children }) =&gt; {
  const [darkMode] = useContext(ModeContext);
  const data = useMetaDataQuery();

  console.log(data)

  return (
    &lt;ThemeProvider theme={darkMode ? darkTheme : lightTheme}&gt;
        &lt;GlobalStyles/&gt;
        &lt;Header siteTitle={data.title}/&gt;
        {children}
    &lt;/ThemeProvider&gt;
  )
}

Question

How to fix the update state code so the error can be resolved ?
Any help will be appreciated, thank you

答案1

得分: 1

你没有提供ModeContext.Provider,你没有将它包含在组件层次结构中(或者如果你包含了,你没有展示代码的这一部分)。

它需要在另一个组件中,这个组件_包含_了你调用useContext(ModeContext) 的所有组件,例如:

import Header from 'components/Header'
import ModeProvider, { ModeContext } from 'context/ModeProvider'

const Layout = ({ children }) => (
    <ModeProvider>
        <InnerLayout>{children}</InnerLayout>
    </ModeProvider>
);

const InnerLayout = ({ children }) => {   
  const [darkMode] = useContext(ModeContext);
  const data = useMetaDataQuery();

  console.log(data)

  return (
    <ThemeProvider theme={darkMode ? darkTheme : lightTheme}>
        <GlobalStyles/>
        <Header siteTitle={data.title}/>
        {children}
    </ThemeProvider>
  )
}
英文:

You don't appear to be providing a ModeContext.Provider – you don't include it in the component hierarchy (or, if you do you're not showing that bit of the code).

It will need to be in another component that encloses all components where you're calling useContext(ModeContext), e.g.

import Header from &#39;components/Header&#39;
import ModeProvider, { ModeContext } from &#39;context/ModeProvider&#39;

const Layout = ({ children }) =&gt; (
    &lt;ModeProvider&gt;
        &lt;InnerLayout&gt;{children}&lt;/InnerLayout&gt;
    &lt;/ModeProvider&gt;
);

const InnerLayout = ({ children }) =&gt; {   
  const [darkMode] = useContext(ModeContext);
  const data = useMetaDataQuery();

  console.log(data)

  return (
    &lt;ThemeProvider theme={darkMode ? darkTheme : lightTheme}&gt;
        &lt;GlobalStyles/&gt;
        &lt;Header siteTitle={data.title}/&gt;
        {children}
    &lt;/ThemeProvider&gt;
  )
}

huangapple
  • 本文由 发表于 2023年4月13日 23:17:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76007139.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定