Context.Consumer无法从提供程序获取价值

时间:2019-04-18 08:29:28

标签: reactjs

我正在尝试使用ContextAPI共享和更新侧边栏的状态。但是,我无法从提供程序获取上下文值。 这是我的代码:

// sidebar-context.js

import React from 'react'

export const SidebarStateContext = React.createContext({
  isOpen: 'true',
  toggleSidebar: () => {},
})

// gatsby-browser.js //我正在使用Gatsby,因此没有App.js。我使用wrapRootElement将提供程序包装在应用程序周围。

import React, { Component } from "react"
import { SidebarStateContext } from "./src/context/sidebar-context"

export default class wrapRootElement extends Component {
  toggleSidebarNow = () => {
    console.log("PLEASE BE OK")
  }

  state = {
    isOpen: false,
    toggleSidebar: this.toggleSidebarNow,
  }

  render(element) {
    return (
      <SidebarStateContext.Provider value={this.state}>
        {element}
      </SidebarStateContext.Provider>
    )
  }
}

// Header.js

import Button from "../atoms/Button"
import { SidebarStateContext } from "../../context/sidebar-context"

class Header extends Component {
  render(siteTitle) {
    return (
      <React.Fragment>
        <StyledHeader>
          <Space height={24} />
          <SpaceWrapper>
            <SidebarStateContext.Consumer>
              {/* {context => <img src={MenuImage} />} */}
              {({ isOpen, toggleSidebar }) => (
                <Button onClick={toggleSidebar}>{isOpen.toString()}</Button>
              )}
            </SidebarStateContext.Consumer>
            <Link
              to="/"
              style={{
                display: "flex",
                justifyContent: "center",
              }}
            >
              <img src={LogoImage} />
            </Link>
            <img src={SearchImage} />
          </SpaceWrapper>
          <Space height={24} />
        </StyledHeader>
        <Divider onDark={true} />
      </React.Fragment>
    )
  }
}

SidebarStateContext.Consumer仅提供上下文文件中的默认值。谁能帮我发现错误?

1 个答案:

答案 0 :(得分:1)

正如the documentation所述,wrapRootElement不是组件,而是具有不同签名的功能。如果提供了组件类,则将其作为常规函数调用,而不用React渲染器实例化。

如果应该有状态组件,则可能应将其与包装器函数分开定义:

export default function wrapRootElement({ element }) {
  return <App>{element}</App>;
}

export class App extends Component {
  ...
  render() {
    return (
      <SidebarStateContext.Provider value={this.state}>
        {this.props.children}
      </SidebarStateContext.Provider>
    )
  }
}