Can someone please help explain this error? I have tried a few different ways to write the React.Component. Is there something missing?
Error:
4:7 warning 'ScrollingHorizontally' is defined but never used no-unused-vars
Component:
import React, { Component } from 'react'
import HorizontalScroll from 'react-scroll-horizontal'
class ScrollingHorizontally extends Component {
render() {
const child = { width: `30em`, height: `100%`}
const parent = { width: `60em`, height: `100%`}
return (
<div style={parent}>
<HorizontalScroll>
<div style={child} />
<div style={child} />
<div style={child} />
</HorizontalScroll>
</div>
)
}
}
I have also tried:
import React from 'react'
import HorizontalScroll from 'react-scroll-horizontal'
class ScrollingHorizontally extends React.Component {
...
To answer your question, the original warning you were receiving is that you defined the variable ScrollingHorizontally but never used it. Even though it is a class it is still a defined variable. It would be easier to demonstrate this error with standard variables:
const things = 123;
const stuff = 456; // this will throw an warning because it is never used.
console.log(things);
The same things happens with classes. If you define a class within a file and never use it, you will receive that warning. Exporting a class from a file will effectively be using it because you are performing the action of exporting it.
--
Why does this error occur?
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.
This is pretty straight forward, you didn't export the class from your file so when you imported the component into your index.js file it didn't find anything. Not all classes within a file automatically get exported, you need to explicitly declare that they should be exported. This allows you to keep certain classes or variables private to a specific file.
MDN - Export (this link breaks down the different types of exporting)
Example with multiple components in one file:
parent.js
import React from 'react';
// This component is not exported, can only be used within
// this file.
class Child extends React.Component {
// ...
}
// This component is not used in the file but is exported to be
// used in other files. (named export)
export class RandomComponent extends React.Component {
// ...
}
// This component is exported as the default export for the
// file. (default export)
export default class Parent extends React.Component {
//...
render() {
return <Child />
}
}
index.js
import React from 'react';
import Parent, { RandomComponent } from './parent.js';
// ...
Related
In my App's React Component library, I have a UIC called Branch which has:
Brand.Logo
Brand.WordMark
Brand.WorkMarkLogo
Brand.Logo and Brand.WordMark work fine but Brand.WorkMarkLogo outputs the following error in storybook:
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.
Please see here: https://codesandbox.io/s/hmfnu
What am I doing wrong?
In the export default pattern, curly braces are not used.
import {Brand} from "./Brand";
correct code.
import Brand from "./Brand";
Only in the 'export' pattern, curly braces are used.
export const abc = () => {};
import {abc} from '...';
When you import and wrap them in curly braces, you're importing a named export, not a default export.
In your brand/index.js file, you have on line 10:
export default Brand;
To import a default export in the module, you'll have to omit the curly braces.
So in your root/index.js file, change line 3 to
import Brand from "./Brand";
Alternatively, you can choose to NOT export a default in your brand/index.js file, and change put the export in front of your class like this:
export class Brand extends React.Component {
static Logo = Logo;
static LogoWordMark = LogoWordMark;
}
With this method, you can add additional classes like in the same brand/index.js file by adding :
export class Brand2 extends React.Component {
static Logo2 = Logo2;
static LogoWordMark2 = LogoWordMark2;
}
Then you'll be able to import both named exports like: https://codesandbox.io/s/react-example-955rf
The component which is external includes and external file
class NavigationBarContainer extends React.PureComponent {
render = () => <NavigationBar extraBanner={<Banner
/>} {...this.props} />
}
in my App
import NavigationBar from '../components/NavigationBar'
<NavigationBar
extraBanner />
doesn't seem to work
import NavigationBarContainer from '../components/NavigationBar'
<NavigationBarContainer {...this.props}>
doesnt seem to work either getting error below
**Invalid prop extraBanner of type boolean supplied to NavigationBar, expected a single ReactElement.**
Two possible things that are wrong here.
1) NavigationBarContainer is not being exported, thus you cannot import it.
You can fix this by making sure to export the class one of two ways -- either change the class declaration to include the export keyword
export default class NavigationBarContainer extends React.PureComponent
or add a line to the bottom of that file
export default NavigationBarContainer;
2) You are trying to import a component called NavigationBarContainer from a file called NavigationBar. If that file is called NavigationBarContainer then this will not work. Make sure that your file names are correct.
A quick summary of export vs export default and importing
export default
The default export can be given any name when imported, eg.
// components/MyComponent.js
export default class MyComponent extends React.Component {...}
// AnotherFile.js
import MyComponent from 'components/MyComponent'; // works
import WhateverName from 'components/MyComponent'; // also works
export
When you don't use the default keyword, then you're making a named export. These have to be imported directly by name, using this syntax:
// components/SmallComponents.js
export class SmallComponent1 extends React.Component {...}
export class SmallComponent2 extends React.Component {...}
// AnotherFile.js
import {SmallComponent1, SmallComponent2} from 'components/SmallComponents'; // works
import SmallComponent1 from 'components/SmallComponents' // does not work
import {WhateverName} from 'components/SmallComponents' // does not work
Hope this helps!
I'm reorganizing the code in my application into a bunch of sub-folders. I'm moving a top-nav component into a subfolder called navigation, this component makes up part of a 'main-nav' container. However, when I shift top-nav into the new folder I start getting the following erro
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.
Check the render method of TopNavTemplate.
I've been reading through a lot of threads and I can't figure out why shifting the poisition would cause this. I've made sure that the component is pointing to the appropriate imports within the file restructure (these errors get thrown before the current error anyway, so it at least thinks that it's pulling everything in correctly.) I also don't think it's a syntax error in the import statement - I'm connecting the top-nav to my redux store as a default export, and I'm not importing it between {}.
Code for the top-nav export can be found below:
import React from 'react';
import {Link} from 'react-router-dom';
import ClickOutside from 'react-click-outside';
import {IconSprite} from '../general/icons.js';
import {Modal} from './modal.js';
import {HeaderSelect} from './select.js';
//Import statements that connect TopNav to the redux store
import * as actionCreators from '../../actions/actionCreator.js';
import { bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import logo from '../../logo.svg';
export class TopNavTemplate extends React.Component {
//Render function and a bunch of code goes here
}
function mapStateToProps(state) {
return {
selectedTarget: state.selectedTarget,
availableTargets: state.availableTargets,
modal: state.modal,
currentUser: state.currentUser,
isLoggedIn: state.isLoggedIn
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(actionCreators, dispatch);
}
const TopNav = connect(mapStateToProps, mapDispatchToProps)(TopNavTemplate);
export default TopNav;
I then import the TopNav into my main-nav layout like so:
import React from 'react';
import TopNav from '../components/navigation/top-nav.js';
import {SideNav} from '../components/side-nav.js';
export class MainNav extends React.Component{
render(){
return ([
<TopNav />,
<SideNav />
])
}
}
If I change the import statement to pull from the old version of the file
import TopNav from ../components/top-nav.js
everything works like a charm. I've even tried removing that file to prevent any kind of web-pack confusion but that doesn't seem to the issue. For some reason, moving this file into a different folder is now causing the export to be undefined instead of a proper react component? Feeling very lost.
It turned out to be a very stupid mistake - I'd forgotten to save one of the files I was importing while shifting everything around. For some reason this wasn't throwing an error that the import couldn't be found, and was instead causing the wrapped connect component to return as undefined.
I'm struggling to dry up a few functions i'm using accross several of my component classes. Mixins are a no-go and I'm struggling to understand what alternative I'm supposed to use. Setting the code up as a module seems promising, but I don't understand how to package it so I can use it to extend several different class.
Say I have:
class functionsToShare {
thingToDo(){
//do a thing
}
}
export default functionsToShare;
I'm assuming in my component class I'd want something like:
import React from 'react';
import functionsToShare from 'some/path'
class SomeComponent extends React.Component{
constructor(props){
super(props);
}
render(){
return (
);
}
}
export SomeComponent
But how do I use the shared class to extend my component? If I declared it inthe class declaration likemy componenet is delcared to extend React.Component that would defeat the reusability... Is there an alternate way I should be looking at?
You can create your shared functions file as a file with several functions that you need to use, each function being exported as a named export. Like this:
export function thingToDo() {
...
}
export function getUserByEmail(email) {
...
}
Save this file as functionsToShare.js, for example.
Then in each React component class (or anywhere else) you can import that functions, just ones you need by:
import {thingToDo} from "./functionsToShare"; // import a function
thingToDo(); // call function
or all of them by:
import * as somename from "./functionsToShare"; // import all functions from that file
somename.thingToDo(); // call specific function
I'm new to reactjs and I'm using it in an electron project. I have component A and B defined in a.jsx and b.jsx separately using the following syntax:
//a.jsx
'use babel';
import React from 'react';
export class A extends React.Component {
render() {
return (
<div>some text</div>
);
}
}
//b.jsx
'use babel';
import React from 'react';
export class B extends React.Component {
render() {
return (
<div>
<A />
</div>
);
}
}
and I render them in the html page:
<!-- index.html -->
<script>
var a = require('./a.jsx');
var b = require('./b.jsx');
React.render(React.createElement(b.B, null), document.body);
</script>
How could I reference component A from component B(e.g. using the A tag in render function of B as illustrated in b.jsx above)? I've tried adding:
import A from './a.jsx'
but got the error:
Uncaught 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 `B`.
What is the right way to do it?
The code above can run without error if the reference of component A is removed in b.jsx.
It's a good idea to stay away from mixing the new module syntax (import, export) with the old commonjs style (require, module.exports).
If your file exports just one component, then you can use a default export.
// a.jsx
import React from 'react';
export default class B extends React.Component {
}
Then you can reference the class using the import syntax in your main file.
import B from './b.jsx';
This is basically shorthand for assigning the default export from this module to a new variable B.
Alternatively, you can have named exports for modules that export multiple values. This is actually what you had before.
export class A extends React.Component {
}
This creates a named export called A that can be referenced from other files with a destructuring import.
import { A } from './a.jsx';
If your file only exports one value it's probably a good idea to stick to default exports.