ReactJS check the render method of `Provider` ContextAPI - reactjs

Hi I'm trying to use Context API and this is my code
App.js
import {Provider} from './components/contexApi/context';
class App extends Component {
render() {
return (
<Provider>
<div className="App">
<Header />
<TodoList />
</div>
</Provider>
);
}
}
And this is my context.js file
context.js
import React, { Component } from 'react'
const Context = React.createContext;
export class Provider extends Component {
state = {
}
render() {
return (
<Context.Provider value={this.state}>
{this.props.children}
</Context.Provider>
)
}
}
export const Consumer = Context.Consumer;
After I save the file the main page says:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of Provider.

React.createContext is a function and you are not calling it.
https://reactjs.org/docs/context.html#reactcreatecontext

Related

Import firebase/firestore not working in Next.js

When I import { collection, getDocs } from "firebase/firestore"; I get this error:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
I have nothing inside my function component and only a <div>hello</div> in JSX.
Edit: The component in project-name/components/Header/index.js
import { collection, getDocs } from "firebase/firestore";
const Header = () => {
return (
<div>hello</div>
);
};
export default Header;
Called in pages/index.js
import Head from "next/head";
import Header from "../components/Header";
export default function Home() {
return (
<div>
<Head>
<title>Site Name</title>
<meta name="description" content="made by..." />
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<Header />
</main>
</div>
);
}
Firebase install: npm i firebase
It works when I import the component: ../components/Header/index, but I get same error when I import the component in a Layout:
import Header from './Header/index'
const Layout = ({children}) => {
return (
<div>
<Header />
<div>{children}</div>
</div>
)
}
export default Layout

How and where do I use the data from an Apollo Client?

How and where do I have to put that query so that I can map through it and display the categories in a header. I'm a noob and all the apollo documentation is made with hooks and functional components, but I have to do this assignment with class based components and I just can't figure it out.
index.js:
const client = new ApolloClient({
uri: "http://localhost:4000/graphql",
cache: new InMemoryCache(),
});
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
document.getElementById("root")
);
App.js:
class App extends Component {
render() {
return (
<>
<Header />
</>
);
}
}
export default App;
Header.js:
class Header extends Component {
render() {
return (
<header>
<ul className="nav-list">
//Display categories here with map in a <li className="nav-item">
</ul>
</header>
)
}
}
query I need for header elements :
const QUERY = gql`
query getCategories {
categories {
name
}
}
`;
Hooks don't work with class components - but you can wrap your class components and pass the hook result as props to the class component:
import React from 'react';
import { useScreenWidth } from '../hooks/useScreenWidth';
export const withQueryHOC = (Component, query) => {
return (props) => {
const { loading, error, data } = useQuery(query);
return <Component loading={loading} error={error} data={data} {...props} />;
};
};
This is called a Higher-Order Component
Where Component is the class component you want to wrap. This way you can use class components but still have access to the hooks.
You should export you component like so:
export default withQueryHOC(YourComponentHere);
In your component you should access loading, error and data through this.props

TypeError: instance.render is not a function while using react-router-dom

Hi If any one can help. Thanks in advance
In console I am also getting this
index.js:1 Warning: AppBootUp(...): No render method found on the returned component instance: you may have forgotten to define render
this is my App.js
import React from "react";
import AppRoutes from "../routes/routers";
import { createStore } from 'redux'
import rootReducer from '../store/reducers/index'
import {Provider} from "react-redux";
const store = createStore(rootReducer);
export default class AppBootUp extends React.Component<> {
static render() {
return (
<Provider store={store}>
<AppRoutes/>
</Provider>
);
}
}
this is my AppRoutes
import React from "react";
import { BrowserRouter as Router, Redirect, Route, Switch } from "react-router-dom";
import Login from "../components/Login/login"
const routesConfig = [
{
path: "/",
component: Login,
name: "Login",
exact: true
}
];
const AppRoutes = () => {
return (
<Router>
<Switch>
{routesConfig.map(config => {
return (
<Route
exact={config.exact && true}
key={`${config.name}`}
path={config.path}
render={(props) => {
const ComponentToRender = config.component;
return <ComponentToRender {...props} />;
}}
/>
);
})}
<Redirect to="/" />
</Switch>
</Router>
);
};
export default AppRoutes;;
this is login.js
import React from "react";
export default class Login extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<p>
hello
</p>
</div>
);
}
}
I am using react-router-dom. I think, I am missing something little here.
Remove static method from render method in AppBootUp class. If you define a render method as static, it won't be available in class instance, which is why you are getting this error.
export default class AppBootUp extends React.Component<> {
render() {
return (
<Provider store={store}>
<AppRoutes/>
</Provider>
);
}
}
You need to remove static before render method of AppBootUp.
render shouldn't be a static property of React class component otherwise it won't exist on component's instance and would become unavailable.
As static properties don't exist on class instance but on the Class itself.
Remove static before render in Appboot.
render should not be a static property of React class component otherwise it won't exist on component's instance.
As static properties don't exist on class instance but on the Class itself.
Normally this happens when you accidentally alt+enter on render in Webstorm.
when it shows warning that this method can be static.

React not rendering multiple components through factory function

The problem is the following, i have a factory:
import React from 'react';
export default (componentFactory) =>
{
return Component =>
{
class Factory extends React.Component
{
render()
{
let { state, props } = this;
return componentFactory({ state, props }, Component);
}
}
return Factory;
};
}
and then a simple Page component wrapper:
import React from 'react';
const Page = ({children, appState}) =>
(
<section>
{React.cloneElement(children, {appState})}
</section>
);
export default Page;
So, in order to create a HomePage, i use HomeFactory likewise:
import React from 'react';
import Factory from '../Factory';
import HeroBanner from '../Banner/HeroBanner';
const HomeFactory = ({state, props}, HomePage) =>
{
return <HomePage {...props} {...state} >
<HeroBanner />
</HomePage>;
};
export default Factory(HomeFactory);
The final code for the HomePage component that is being mounted, is then as follows:
import React from 'react';
import Page from '../Page';
import HomeFactory from '../HomeFactory';
const HomePage = ({children, appState}) =>
{
return (
<Page appState={appState}>
{children}
</Page>
);
};
export default HomeFactory(HomePage);
The problem seems to be the HomeFactory component, in which i put:
return <HomePage {...props} {...state} >
<HeroBanner />
</HomePage>;
as per example given, and this works 100% correctly, however, when i try to put multiple components in form of array or just many components nested in, like:
return <HomePage {...props} {...state} >
<HeroBanner />
<HeroBanner />
<HeroBanner />
</HomePage>;
I am getting the following error:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.
Basically, the Page wrapper component is getting properties passed in as children of its parent component HomePage, and these are taken from the factory method.
The question is what is happening implicitly with JSX that I cannot do the following?
In your Page component you need to use cloneElement along with Children.map when you pass multiple children (this.props.children is then a special array-like object)
See this answer: stackoverflow.com/a/38011851/3794660 for more details.

Unable to implement Leftnav with AppBar component in material-ui

I am having a lot of trouble trying to implement material-ui's AppBar with Leftbar as there seems to be lots of different variations on component declaration/imported dependencies syntax and components. I can't even find proper documention on http://www.material-ui.com/ about Leftnav in the first place, all they give with Appbar is a static hamburger menu example. My code is as follows:
import React, { Component } from 'react'
import { LeftNav, AppBar} from 'material-ui'
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import { Router, Route, Navigation, Link, browserHistory } from 'react-router'
export default class Header extends Component {
getChildContext() {
return {muiTheme: getMuiTheme(baseTheme)};
}
_toggleNav(){
this.refs.leftNav.toggle();
}
render() {
const data = this.props.data
const nav_items = data.globals.nav_items
//Menu item links
const menu_items = nav_items.map(( nav_item ) => {
return (
<span key={ 'key-' + nav_item.value }>
<Link to={ '/' + nav_item.value }>{ nav_item.title }</Link>
</span>
)
})
return (
<div>
<LeftNav ref='leftNav'
docked={false}
menuItems={ menu_items } />
<AppBar title="App Bar Example" onLeftIconButtonTouchTap={this._toggleNav}
isInitiallyOpen={true} />
</div>
)
}
}
Header.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
};
I am getting to obscure errors which explain me nothing about what am actually doing wrong:
VM15235:27 Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method of `Header
and:
invariant.js:38 Uncaught (in promise) Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. Check the render method of `Header`.(…)
Is there a way of making this more explicit?
There was a change to material-ui that renamed LeftNav to Drawer! It seems like certain docs/examples haven't been updated. So if you use Drawer you will find documentation and it should work! Here is the commit/thread from the change away from LeftNav.
https://github.com/callemall/material-ui/issues/2697

Resources