简体   繁体   中英

Context Components in React 16.3 are invalid

I'm trying to use the new Context components in React 16.3.1. I'm running a pretty straightforward example:

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>
    );
  }
}

However the code won't render, instead producing this error:

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

It seems that both the Provider and Consumer components aren't valid components and can't be rendered by React.

Am I missing something here?

Figured it out!

I updated React to 16.3.1, but didn't update ReactDOM.

Running npm uninstall -s react-dom && npm i -s react-dom updated it to 16.3.1 and fixed the issue.

Side note, I wouldn't have expected the new Context API to be dependent on ReactDOM.

For your current situation you must return a react element in the TestContext.Consumer .

The Provider component is used higher in the tree and accepts a prop called value (which can be anything).

The Consumer component is used anywhere below the provider in the tree and accepts a prop called “children” which must be a function that accepts the value and must return a react element (JSX).

Make sure you render <Test /> and not <TestContext /> and you must be on react and react dom 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"));

An example of how to do it with 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"));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM