React 16.3中的上下文组件无效

时间:2018-04-05 01:20:37

标签: javascript reactjs

我正在尝试在React 16.3.1中使用新的Context组件。我正在运行一个非常简单的例子:

const TestContext = React.createContext();

export default class Test extends Component {
  render () {
    return (
      <TestContext.Provider value="abc">
        <TestContext.Consumer>
          {value => (
            <div>{value}</div>
          )}
        </TestContext.Consumer>
      </TestContext.Provider>
    );
  }
}

但是代码不会呈现,而是产生此错误:

Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

似乎Provider和Consumer组件都不是有效组件,并且不能由React呈现。

我在这里错过了什么吗?

2 个答案:

答案 0 :(得分:17)

想出来了!

我将React更新为16.3.1,但没有更新ReactDOM。

正在运行npm uninstall -s react-dom && npm i -s react-dom将其更新为16.3.1并解决了问题。

旁注,我不希望新的Context API依赖于ReactDOM。

答案 1 :(得分:0)

对于您目前的情况,您必须在TestContext.Consumer中返回一个react元素。

  

提供程序组件在树中使用得更高,接受道具   叫值(可以是任何东西)。

     

使用消费者组件   树中提供者下方的任何地方,并接受一个名为的道具   “孩子”必须是接受价值的函数,而必须   返回一个反应元素(JSX)。

确保你渲染<Test />而不是<TestContext />,你必须做出反应并做出反应16.3.1。

const TestContext = React.createContext();

class Test extends React.Component {
  render() {
    return (
      <TestContext.Provider value="abc">
        <TestContext.Consumer>{value => <div>{value}</div>}</TestContext.Consumer>
      </TestContext.Provider>
    );
  }
}

render(<Test />, document.getElementById("root"));

如何使用this.props.children

执行此操作的示例
import React from "react";
import { render } from "react-dom";

const TestContext = React.createContext();

class TContext extends React.Component {
  state = {
    value: "abc"
  };
  render() {
    return (
      <TestContext.Provider
        value={{
          state: this.state
        }}
      >
        {this.props.children}
      </TestContext.Provider>
    );
  }
}

class Child extends React.Component {
  render() {
    return (
      <TContext>
        <TestContext.Consumer>
          {context => <div>{context.state.value}</div>}
        </TestContext.Consumer>
      </TContext>
    );
  }
}

render(<Child />, document.getElementById("root"));