javascript - 尝试使用 Context API 时看到 "render is not a function"

标签 javascript reactjs

我正在尝试学习 Context API,而我想要实现的是在我的标题中显示已登录用户,以及根据登录状态操作我的菜单选项(存储 ' 是否安全isAuthenticated' 状态?)

我的上下文类:

import React from 'react';

const Context = React.createContext();

export class Provider extends React.Component {

    state = {
        isAuthenticated: true,
        user: {
            name: "Joe Smith",
            email: "joe.smith@here.com"
        }
    }

    render() {
        return (
            <Context.Provider value={this.state}>
                {this.props.children}
            </Context.Provider>
        )
    }
}

export const Consumer = Context.Consumer;

所以,非常基础。设置一个状态,在后面的一些子组件中,我想显示小伙子的名字。

我的 App.js 正在使用“Provider”,因此我的所有组件都可以访问此数据:

import React from 'react';
import { HashRouter , Route, Switch } from 'react-router-dom';
import Home from './components/home';
import Header from './components/header';
import Accounts from './components/accounts';
import Reports from './components/reports';
import Login from './components/login';
import {Container} from 'reactstrap';

import { Provider } from './context';

function App() {
  return (
    <div className="App">
      <Provider>
        <HashRouter>
          <Header />
          <Container>
            <Switch>
              <Route exact path="/" component={Home} />
              <Route exact path="/accounts" component={Accounts} />
              <Route exact path="/reports" component={Reports} />
              <Route exact path="/login" component={Login} />
            </Switch>
          </Container>
        </HashRouter>
      </Provider>
    </div>
  );
}

export default App;

所以在这种情况下,'Header' 需要访问我的上下文。 我的标题将显示一个菜单(根据我将添加到上下文的一些信息,该菜单将显示或隐藏选项、登录按钮等)。

在菜单下,我想显示一个小信息栏。例如登录的用户名。所以,我的标题类看起来像这样:

import React from 'react';
import Menu from './menu';
import InfoBar from './infobar';
import { Consumer } from '../context';

class Header extends React.Component {

    render() {
        const menuStyle = {
            paddingBottom: "5px"
        }

        return(
            <Consumer>
                <div style={menuStyle}>
                    {value => {
                        console.log(value);
                        return (
                            <h1>Test</h1>
                        )
                    }}
                    <Menu  />
                    <InfoBar />
                </div>
            </Consumer>
        )
    }
}

export default Header;

但是现在问题来了。当我运行我的代码时,它编译并运行,但我立即收到运行时错误:

TypeError: render is not a function updateContextConsumer C:/Storage/Scratch/ReactApp/accufinance/node_modules/react-dom/cjs/react-dom.development.js:16082

我阅读了一些关于返回和多个 child 的内容,但我的代码似乎没有这个问题。任何帮助理解问题和问题发生的地方都会很棒。如果我注释掉'header'中的代码,没有错误......但是......也没有屏幕。它似乎正在该地区发生。

最佳答案

Context Consumer 使用 render prop,特别是函数作为子组件,因此它期望其直接子组件是函数(而不是组件)。在您的情况下,您只需在函数内移动 div:

<Consumer>
  {value => {
    console.log(value);
    return (
      <div style={menuStyle}>
        <h1>Test</h1>
        <Menu />
        <InfoBar />     
      </div>
    )
  }}
</Consumer>

当您想要将组件的内部状态暴露给它的子组件时,但当您还想将它用于不同类型的子组件时,Render props 非常强大。

模式是这样的:

class Parent extends Component {
  state = { name: 'Mike' }

  handleChange = (e) => this.setState({ name: e.target.value })

  render() {
    // Here's the main difference: We expect `children` to be
    // a function, and we pass name in as the argument
    return children(state.name);
  }
}

const InputChild = props => <input value={props.name} />

const HeaderChild = props => <h1>{props.name}</h1>

const App = () => {
  return (
    <Parent>
      {name => {
        // We could easily swap in `HeaderChild` here (or
        // anything else!), passing `Parent`'s internal
        // state.name to it instead:
        <InputChild name={name} />
      }
    </Parent>
  )
}

这就是 Context 起作用的原因,因为消费者对其子组件中的组件一无所知,但它可以公开其状态(这是来自提供者的值)。

React 文档有一个关于渲染 Prop 的重要部分:https://reactjs.org/docs/render-props.html

关于javascript - 尝试使用 Context API 时看到 "render is not a function",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56571818/

相关文章:

javascript - 如何在 React v6 中重定向

javascript - jQuery 插件 - 这些设置如何工作?

javascript - 使用 unstated.js 进行解构

javascript - JS中通过空格分割文本

javascript - 加载项行为多个打开的 Word 文档

javascript - 外部化各种 React 组件中的通用函数

reactjs - 使用 testing-library 和 jest 的 React 组件抛出的测试错误

javascript - 使用 anchor 标记<a>下载文件时如何获取下载时间?

reactjs - 使用 babel polyfill 后,bundle.js 仍然包含箭头函数和默认参数

javascript - 为表中的内部按钮设置类并延迟加载数据