1

I am new to React ans was learning Context API and during the use of it I faced this error TypeError: render is not a function. I also found the this answer React Context: TypeError: render is not a function in the platform which is close to my problem but no result. Here is the code I am using:

import React, { Component } from "react";
import MyContext from "../../Containers/Context/Context";
class Track extends Component {
  render() {
    return (
      <MyContext>
        {value => {
          return <div>{value.heading}</div>;
        }}
      </MyContext>
    );
  }
}

export default Track;

import React, { Component } from "react";

const Context = React.createContext();

export class MyContext extends Component {
  state = { track_list: [], heading: "Top Ten Tracks" };
  render() {
    return (
      <Context.Provider value={this.state}>
        {this.props.children}
      </Context.Provider>
    );
  }
}

export default MyContext = Context.Consumer;

import React, { Component, Fragment } from "react";
import "./App.css";
import Header from "../src/Components/Header/Header";
import Search from "../src/Components/Search/Search";
import Tracks from "../src/Components/Tracks/Tracks";
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import NotFound from "./Components/NotFound/NotFound";
import MyContext from "./Containers/Context/Context";

class App extends Component {
  render() {
    return (
      <MyContext>
        <Router>
          <Fragment>
            <Header />
            <div className="container">
              <Search />
              <Switch>
                <Route exact path="/" component={Tracks} />
                <Route component={NotFound} />
              </Switch>
            </div>
          </Fragment>
        </Router>
      </MyContext>
    );
  }
}

export default App;
5
  • 1
    You never mount the context provider, so why would you expect your consumer to work? FYI, context only works when Context.Provider is a parent of Context.Consumer. You need to wrap your app in the context provider. Also, look at your export statements. You export MyContext as a named export, and you export Context.Consumer as MyContext(by overwriting the value of MyContext in your export statement) as the default export. there's all kinds of wtf going on here Commented Sep 24, 2019 at 15:52
  • @r3wt, thanks dude for your kind attention and help. Gosh so hard to be beginner:) Commented Sep 24, 2019 at 16:05
  • is ok, trust me my first journey with context was very similar :-) glad it helped Commented Sep 24, 2019 at 16:07
  • @r3wt, sorry dude just wanted to ask you kind advice. Is it ok to use Context API when there is Parent->Child two level relationship instead of prop-drilling? Or Should we consider using Context API when there are more than 3 level relationship? Thank you:) Commented Sep 24, 2019 at 16:12
  • 1
    a general rule of thumb is that if more than 1 sibling needs access to a state of some parent of n depth, then i will probably use a context provider just to avoid the prop drilling. Sometimes this includes a direct child of the parent component, but often the nesting is as you say >=3 deep. Truthfully though, i avoided context at my own peril in the past so now i am much more eager to find ways to make it work, just to avoid the unmaintainability of prop drilling and juggling events and state across multiple components Commented Sep 24, 2019 at 16:30

1 Answer 1

1

Your export and import statements are problematic.

first you export class MyContext then you immediately overwrite MyContext with Context.Consumer.

Fix your export statements and then fix your imports. import the Context.Consumer in file Track, and import the Context.Provider in file App

Containers/Context/Context.js

import React, { Component } from "react";

const Context = React.createContext();

class MyContextProvider extends Component {
  state = { track_list: [], heading: "Top Ten Tracks" };
  render() {
    return (
      <Context.Provider value={this.state}>
        {this.props.children}
      </Context.Provider>
    );
  }
}

const MyContextConsumer = Context.Consumer;

export {MyContextProvider,MyContextConsumer};

Track.js

import React, { Component } from "react";
import {MyContextConsumer} from "../../Containers/Context/Context";
class Track extends Component {
  render() {
    return (
      <MyContextConsumer>
        {value => {
          return <div>{value.heading}</div>;
        }}
      </MyContextConsumer>
    );
  }
}

export default Track;

App.js

import React, { Component, Fragment } from "react";
import "./App.css";
import Header from "../src/Components/Header/Header";
import Search from "../src/Components/Search/Search";
import Tracks from "../src/Components/Tracks/Tracks";
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import NotFound from "./Components/NotFound/NotFound";
import {MyContextProvider} from "./Containers/Context/Context";

class App extends Component {
  render() {
    return (
      <MyContextProvider>
        <Router>
          <Fragment>
            <Header />
            <div className="container">
              <Search />
              <Switch>
                <Route exact path="/" component={Tracks} />
                <Route component={NotFound} />
              </Switch>
            </div>
          </Fragment>
        </Router>
      </MyContextProvider>
    );
  }
}

export default App;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.