How to import and export components using React + ES6 + webpack? - reactjs

I'm playing around with React and ES6 using babel and webpack. I want to build several components in different files, import in a single file and bundle them up with webpack
Let's say I have a few components like this:
my-navbar.jsx
import React from 'react';
import Navbar from 'react-bootstrap/lib/Navbar';
export class MyNavbar extends React.Component {
render(){
return (
<Navbar className="navbar-dark" fluid>
...
</Navbar>
);
}
}
main-page.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import MyNavbar from './comp/my-navbar.jsx';
export class MyPage extends React.Component{
render(){
return(
<MyNavbar />
...
);
}
}
ReactDOM.render(
<MyPage />,
document.getElementById('container')
);
Using webpack and following their tutorial, I have main.js:
import MyPage from './main-page.jsx';
After building the project and running it, I get the following error in my browser console:
Error: Invariant Violation: 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 `MyPage`.
What am I doing wrong? How can I properly import and export my components?

Try defaulting the exports in your components:
import React from 'react';
import Navbar from 'react-bootstrap/lib/Navbar';
export default class MyNavbar extends React.Component {
render(){
return (
<Navbar className="navbar-dark" fluid>
...
</Navbar>
);
}
}
by using default you express that's going to be member in that module which would be imported if no specific member name is provided. You could also express you want to import the specific member called MyNavbar by doing so: import {MyNavbar} from './comp/my-navbar.jsx'; in this case, no default is needed

Wrapping components with braces if no default exports:
import {MyNavbar} from './comp/my-navbar.jsx';
or import multiple components from single module file
import {MyNavbar1, MyNavbar2} from './module';

To export a single component in ES6, you can use export default as follows:
class MyClass extends Component {
...
}
export default MyClass;
And now you use the following syntax to import that module:
import MyClass from './MyClass.react'
If you are looking to export multiple components from a single file the declaration would look something like this:
export class MyClass1 extends Component {
...
}
export class MyClass2 extends Component {
...
}
And now you can use the following syntax to import those files:
import {MyClass1, MyClass2} from './MyClass.react'

MDN has really nice documentation for all the new ways to import and export modules is ES 6 Import-MDN . A brief description of it in regards to your question you could've either:
Declared the component you were exporting as the 'default' component that this module was exporting:
export default class MyNavbar extends React.Component { , and so when Importing your 'MyNavbar' you DON'T have to put curly braces around it : import MyNavbar from './comp/my-navbar.jsx';.
Not putting curly braces around an import though is telling the document that this component was declared as an 'export default'. If it wasn't you'll get an error (as you did).
If you didn't want to declare your 'MyNavbar' as a default export when exporting it : export class MyNavbar extends React.Component { , then you would have to wrap your import of 'MyNavbar in curly braces:
import {MyNavbar} from './comp/my-navbar.jsx';
I think that since you only had one component in your './comp/my-navbar.jsx' file it's cool to make it the default export. If you'd had more components like MyNavbar1, MyNavbar2, MyNavbar3 then I wouldn't make either or them a default and to import selected components of a module when the module hasn't declared any one thing a default you can use: import {foo, bar} from "my-module"; where foo and bar are multiple members of your module.
Definitely read the MDN doc it has good examples for the syntax. Hopefully this helps with a little more of an explanation for anyone that's looking to toy with ES 6 and component import/exports in React.

I Hope this is Helpfull
Step 1: App.js is (main module) import the Login Module
import React, { Component } from 'react';
import './App.css';
import Login from './login/login';
class App extends Component {
render() {
return (
<Login />
);
}
}
export default App;
Step 2: Create Login Folder and create login.js file and customize your needs it automatically render to App.js Example Login.js
import React, { Component } from 'react';
import '../login/login.css';
class Login extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
export default Login;

There are two different ways of importing components in react and the recommended way is component way
Library way(not recommended)
Component way(recommended)
PFB detail explanation
Library way of importing
import { Button } from 'react-bootstrap';
import { FlatButton } from 'material-ui';
This is nice and handy but it does not only bundles Button and FlatButton (and their dependencies) but the whole libraries.
Component way of importing
One way to alleviate it is to try to only import or require what is needed, lets say the component way. Using the same example:
import Button from 'react-bootstrap/lib/Button';
import FlatButton from 'material-ui/lib/flat-button';
This will only bundle Button, FlatButton and their respective dependencies. But not the whole library. So I would try to get rid of all your library imports and use the component way instead.
If you are not using lot of components then it should reduce considerably the size of your bundled file.

Related

Element type invalid within React project - Import issue?

Within my React application, I'm met with an issue which seems to be related to imports or extending Component | React.Component with my main App class.
The error I'm met with is:
Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: undefined.
I assumed it might have to do with default vs named import of Component, but even when using React.Component instead of Component, I'm met with this issue.
Is there any reason why this would occur?
The import statements I've used are structure as such, below:
import React from 'react';
import Component from 'react';
import './App.css';
import Exercises from "./components/ExerciseDay";
import MySurvey from "./components/MySurvey";
import ExerciseSelector from "./components/ExerciseSelector";
import ToggleDisplay from 'react-toggle-display';
export default class App extends React.Component {
render() {
const surveyCompleted = localStorage.getItem("experience");
return (
<div className="App">
<header className="App-header">
<h1 className="App-title" style={{fontFamily: "Comfortaa, cursive", fontSize: 35}}>
Sheiko Workout Finder
</h1>
</header>
<ToggleDisplay show={!surveyCompleted} tag="section">
<MySurvey/>
</ToggleDisplay>
<ToggleDisplay show={surveyCompleted !== null}>
<ExerciseSelector/>
<Exercises/>
</ToggleDisplay>
<footer style={{fontFamily: "Comfortaa, cursive", fontSize: 20}}>
<p>
Note here -
</p>
</footer>
</div>
);
}
}
A Component is named export. Instead of import Component from 'react';
it should be import { Component } from 'react'; //with curly braces
But you are not using it. It can be deleted because you are using React.Component.
Most likely there is another problem because there is not shown how you are exporting other components from other files ( ExerciseDay,MySurvey,ExerciseSelector ) they or something from them might be named export instead of default export. Check how you are exporting them
And there is another case that will cause this error. If you are importing something wrong also in these components. For example, something imported in ExerciseDay from another file is incorrect. Like exported as named export instead of default export or vice versa

how to use Context for class Component in other module in React js

when i use context in Reactjs ,by using hooks I just can use 'useContext' for function component in other module , but I want to use it for --> class component <-- in other module but i cant do it, and in browser console i see this error: ==>> ((
ReferenceError: Cannot access 'MyContext' before initialization
Module.MyContext
http://localhost:3000/static/js/main.chunk.js:12:101
Module../src/news.js
F:/0 React Js project/my-appfirst-app/src/news.js:21
))
do we have any way to use class component in other module?
these are my codes
parent commponent:
import React,{createContext,Component} from 'react';
import ReactDOM from 'react-dom';
import Roots from './news'
import * as serviceWorker from './serviceWorker';
export let MyContext=createContext();
class Show extends Component{
render(){
return(
<MyContext.Provider value={{name:'ali',family:'mohammady',done:'false'}} >
<div className='container-main'>
<Roots />
</div>
</MyContext.Provider>
)
}
}
ReactDOM.render(<Show />, document.getElementById('root'));
and this child module:
import React,{Component} from 'react';
import {MyContext} from './index'
class Roots extends Component{
static contextType = MyContext;
render(){
return(
<>
<p>{console.log(this.context)}</p>
</>
)
}
}
export default Roots;
I wonder how to work this codes if i put child component in parent component !!??
You need to export then import the consumer from the context to use it like that
export let MyContext=createContext();
export const MyContextConsumer = MyContext.Consumer
Then import that consumer and use it
import React,{ Component } from 'react';
import { MyContextConsumer } from './index'
class Roots extends Component{
render(){
return(
<MyContextConsumer>
{value => <p>{console.log(value)}</p>}
</MyContextConsumer>
)
}
}
#topched
thanks for your help
your answer is very helpful for me but the console show the error again and then I did a few changes on your code and it runs without error.
when I use bottom script in index.js , i get error but i created a new file with the name context.js and put bottom script in it , the codes run without error
export let MyContext=createContext();
export const MyContextConsumer = MyContext.Consumer

React create app - How do you import a nested component?

I am using React create app and I understand how to import a component into my main app which is called app.js.
What I do not understand is how I import a component in a component which is then imported in app.js (nested component).
In my app.js file, I have a component called Portfolio. In my portfolio.js file, I have a component called Language. Is it even possible to nest components with React create app? Because it does not seem to work.
This is what I tried to do:
In my app.js file :
import React from "react";
import logo from "./logo.svg";
import "./App.css";
import Portfolio from './components/portfolio';
import "./css/styles.css"
function App() {
return (
<div className="App">
<header>
<h1>My beautiful title</h1>
</header>
<Portfolio />
</div>
);
}
export default App;
In my portfolio.js file :
import React, {Component} from 'react';
import Language from './components/language';
class Portfolio extends Component {
render() {
return (
<div className="portfolio">
<Language/>
<h1>My protfolio</h1>
</div>
);
}
}
export default Portfolio;
And in language.js I have:
import React, {Component} from 'react';
class Language extends Component {
render() {
return(
<div>Switch language</div>
);
}
}
export default Language;
In my browser, I keep getting the following error:
"./src/components/portfolio.js Module not found: Can't resolve
'./components/language' in
'C:\Users\mluce\exercice-react\src\components'"
My language.js file is definitely sitting in my components folder. I do not understand why I get this error?
In portfolio.js:
import Language from './language';

React unable to find component

I'm trying to create a React App.. largely my attempts so far are based on the default application from create-react-app. Here's my App.js:
import React from 'react';
import './App.css';
import './Components/MyComponent';
function App() {
return (
<div className="App">
<MyComponent/>
</div>
);
}
export default App;
MyComponent is defined here:
import React from 'react';
import img from './Assets/img.png';
import imgComponent from './MyImage';
class MyComponent extends React.Component {
render() {
return
<div>
<imgComponent imageProp={img} />
</div>
}
}
export default MyComponent;
When I run this, I get the error:
./src/App.js
Line 8: 'MyComponent' is not defined react/jsx-no-undef
Please could someone tell me why I'm getting this error? I was under the impression that a combination of the import in App.js and the export default in MyComponent was all that was needed to use the component.
In the App.js you added MyComponent to the render method, but MyComponent is not defined in your code (as the error message says).
Just change your third import:
import './Components/MyComponent';
To:
import MyComponent from './Components/MyComponent';
So you got the component you are using in your render function.
I hope it helps!
When we are doing export default Mycomponent, we are exposing the Mycomponent module to other modules. But we require a local name to access the contents. For a default export, it doesn't have to be the same as export. A simple import statement should look like import name from 'module'.
In your case, it will be
import MyComponent from './Components/MyComponent'.

"Shallow" test requests underlying modules. Why does it go deeper?

If I understand right the shallow test must not go deeper the the module which is been tested. Why do I get the displayed error?
App.js looks like:
import * as React from 'react';
import './css/app.css';
import Router from './Router';
import Map from './containers/Map';
import MainTools from './components/ui/MainTools';
class App extends React.Component {
render() {
return (
<div className="App">
<Map />
<MainTools />
<Router />
</div>
);
}
}
export default App;
MapActions.tsx is used inside Map.
Thanks!
It doesn't mount the children components but it still is going to import the files and when it hits an import it can't find there will still be an error. You are probably trying to import an object that doesn't exist.

Resources