Cannot find module whenever I add another component to React JS - javascript

I am working through a Udemy Tutorial on React, and something here does not make sense. Whenever I try to add a new component to a .js file, I get an error stating that the component file cannot be found. Here is what I mean:
Originally, I had these 2 files:
my main.js :
console.log('Hello World!');
import React from 'react';
import ReactDOM from 'react-dom';
import Channel from './Channel';
document.addEventListener('DOMContentLoaded', function() {
ReactDOM.render(
React.createElement(Channel, Object.assign({}, this.props, {name:'Ryan'})),
document.getElementById('My-Channel')
);
});
and my Channel
import React from 'react';
class Channel extends React.Component {
onClick(){
console.log('I was clicked');
}
render(){
return(
<li onClick={this.onClick.bind(this)}>{this.props.name}</li>
)
}
}
export default Channel;
This code actually works, and displays the proper 1 item list.
However, when I try to add another component to my Channel.js file, it breaks. No matter what I put in, it seems that adding another component does not work.
Ex :
import React from 'react';
class Channel extends React.Component {
onClick(){
console.log('I was clicked');
}
render(){
return(
<li onClick={this.onClick.bind(this)}>{this.props.name}</li>
)
}
}
class ChannelList extends React.Component{
render(){
return (
<ul>
<Channel name='Hardware Support'>
</ul>
)
}
}
export default Channel;
Do I have to create a new file every time I want to create a component? I can't imagine that being the case, so what would you suggest I do?
Here is the Exact Error I am getting
Even if I add a simple dictionary to the end of the file, I get the same error. Its as if the only thing in this Channel.js file can be the channel component
Thank you in advance for your help!

Not being able to find a module is almost always a sign of a syntax error (assuming the files are in the right location). In your case, it's never hitting export because the following is a syntax error:
class ChannelList extends React.Component{
render(){
return (
<ul>
<Channel name='Hardware Support'>
</ul>
)
}
}
You're missing the closing tag!
Change <Channel name='Hardware Support'> to <Channel name='Hardware Support' />
Also it looks as though you should be doing:
export default ChannelList
and in your main file:
import ChannelList from './Channel'
ReactDOM.render(
<ChannelList />,
document.getElementById('My-Channel')
),

Credit to #jamesemanon for part of the solution, and #azium for the other.
So, of the problems that I had:
make sure to close your tags
for some reason, I had to use export default instead of just
export
I had to import ChannelList into my main.js file : import
ChannelList from './Channel';
Thank you both for your help, I hope some others can benefit from this in the future as well

Related

`npm init react-app` leads to `'React' is not defined no-undef` when changing function component to class component

I used npm init react-app appname which creates, among other files, App.js. In that file is a function component:
function App() {
return (
<SomeJSX />
);
}
I edited the function component into a class component, like so:
class App extends React.Component{
render() {
return (
<TheSameJSX />
);
}
}
Now, when I run npm start, I get an error:
Failed to compile
src/App.js
Line 4:19: 'React' is not defined no-undef
Search for the keywords to learn more about each error.
I imagine I need to add some setting somewhere that will automatically include React without me needing to explicitly import it at the top of every file. How do I do this? And why does this npm package not do that by default? I know a bit about javascript (and html and css), and have read a bit about React, but I am completely unaware of how npm or webpack works.
Thanks in advance!
EDIT: To clarify, I know how to import stuff with javascript. I can easily add import React from 'react'; to the file and make it work. However, I find it difficult to believe that adding an import statement to every single javascript file is the recommended method, and I don't understand why this example app wouldn't be set up so as to avoid having to do that. Am I mistaken? Do I really need to manually import the same thing over and over again within the same project? Could I set a global variable to React so that I can use it from wherever?
In your default function component you're not extending any classes and just writing a simple function
function App() {
return (
<SomeJSX />
);
}
In class component, you're in fact extending the Class Component by React.Component provided by React default export object and hence you must import it from the package
//only use one of these
import * as React from "react";
import {Component} from "react"; // you can directly extend without writing `React.` with this import
import React from "react"
So your code would be
import React from "react";
class App extends React.Component{
render() {
return (
<TheSameJSX />
);
}
}
Any of the above imports should be fine with a preference to the first and second one.

How do I navigate to a different route in my react application?

I want to create new Routes for my works web application, but the way that they are using the Routes is not the way I thought they would be used. Essentially I want to add new routes and be able to click on say like a button, and that will take me to the desired route that I want to go to.
The way it is set up in our application is that you actually have to manually go in the browser and type in the extended path to access that route, which doesn't seem like a good way of doing it.
Right now I have a route set up for our inventory system. You would access this route by typing in localhost::3000/inventory. There are buttons that come up on this main page which when clicked render that specific component. Instead of doing it that way, I would rather set up another route like /additem to the inventory path so that when I click on the Add Item button it will take me to the path localhost::3000/inventory/additem and render that component.
This is what our index.js file looks like for reference
import "babel-polyfill";
import 'core-js/es6/map';
import 'core-js/es6/set';
import 'core-js/fn/array/find';
import 'core-js/fn/array/includes';
import 'core-js/fn/number/is-nan';
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import ServiceReport from './imports/ServiceReportUI/ServiceReport'
import './StyleSheets/ServiceReport.css';
import InventorySystem from './imports/InventorySystem/InventorySystem.js';
import AddNewItemBtn from "./imports/InventorySystem/AddNewItemBtn";
import { BrowserRouter, Route, Link, Switch } from 'react-router-dom'
ReactDOM.render((
<BrowserRouter>
<Switch>
<Route exact path='/' component={App}/>
<Route path='/service' component={ServiceReport} />
<Route exact path='/inventory' component={InventorySystem} />
</Switch>
</BrowserRouter>), document.getElementById('appRoot'));
I'm thinking that adding another route like so will do the trick:
<Route exact path='/inventory/additem' component={AddItem} />
And I would access that route from within my InventorySystem.js file by doing something like this:
Class InventorySystem extends React.Component{
constructor(props){
super(props);
this.state = {}
}
goTo(e){
//go to Add Item path
}
render(){
return(
<button onClick={this.goTo.bind(this)}>Add Item</button>
)
}
}
I don't know much about React Router, and I'm also not sure if this is the right way of going about this, but any help or suggestions would be awesome!
The way to navigate within a React-Router setup is by using the Link component provided by the repo. Your first suggestion to create an additional Route for the AddItem component is correct. Simply import the Link component and define the expected path to go to.
import { Link } from "react-router-dom
class InventorySystem extends React.Component{
constructor(props){
super(props);
this.state = {}
}
render(){
return(
<Link to="/addItem">Add Item</Link>
)
}
}
You can style the Link to look like a button if needed as it does accept a className property.
You have 2 options, both included in example below
import { Link } from "react-router-dom";
class InventorySystem extends React.Component {
constructor(props) {
super(props);
this.state = {}
}
goTo(e) {
// option 1
this.props.history.push('/inventory/additem');
}
render() {
return (
<div>
<button onClick={this.goTo.bind(this)}>Add Item</button> // option 1
<Link to="/inventory/additem">Add Item</Link> // option 2
</div>
)
}
}

Error in App class when using React-Redux "connect "

I am receiving the following error when trying to use the connect() function from react-redux:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Check the render method of `App`.
This is App:
import { Provider } from 'react-redux';
import configureStore from './store';
const App = class extends React.PureComponent {
render() {
const { title } = this.context;
return (
<div className="center-screen">
{title}
<Provider store={configureStore()}>
<Chat />
</Provider>
</div>
);
}
};
This is the relevent code end of chat:
import { connect } from 'react-redux';
...
const mapStateToProps = state => ({
...state
});
const mapDispatchToProps = dispatch => ({
addMessage: () => dispatch(addMessage)
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(Chat);
When using : "export default Chat" instead of connect, it's working fine..
Try this:
const ConnectedChat = connect(
mapStateToProps,
mapDispatchToProps
)(Chat);
export default ConnectedChat;
Or you may wish to rename the class definition to ConnectedChat and reverse the names so you can import it as just Chat.
Edit: Also make sure you're importing the Chat component in the App file, as well as the addMessage action creator if you're not.
Where are you defining Chat the component in your connect function?
My usual set up is (I'm using class but const ConnectedChart() would still be this same set up)
class ConnectedChart extends Component {
//// All code here render and return etc
}
const Chart = connect (mapStateToProps)(ConnectedChat);
export default Chart;
So that way you are essentially assigning a component to Chart with the connect statement and then you export default. I think exporting the connect statement directly might by throwing an error but if that doesn't work post the full chart component and I'll see if there is something else going on
EDIT: based on the full code
try this in your App.js:
import React from "react";
import ReactDOM from 'react-dom';
import "./App.css";
import ConnectedChat from "./Chat";
import { Provider } from "react-redux";
import configureStore from "./store";
ReactDOM.render(
<Provider store={configureStore()}>
<ConnectedChat />
</Provider>
);
and then put your div center screen in ConnectedChat
(if you are going to be adding more components later and want that div wrapping all of them, create a main app component like landing or something and call that between your provider instead of chat, and then in that landing component render the div and your ChatComponent)
Also if you don't have an index.js change the 'main' in your package.json to this App.js component

I can't Pass custom props to "export default"

Sorry for the noob question, i'm completely new to this, so here it goes:
I'm practicing react and normally when i do something like:
var Person = function(props){
return(
<h1>Hi, {props.name}</h1>
);
}
ReactDOM.render(
<Person name="Jon"/>,
document.getElementById("app")
);
i would see: "Hi, Jon"
but the thing is, i'm now using create-react-app and there instead of ReactDOM.render(), i just have:
export default Person;
and i don't know how to inject my props into "Person" in order to see "Hi, Jon"
i tried guessing solutions like:
export default Person(name:'Jon');
or things like that but of course it doesn't work.
I dont have enough information to google the right question even though i tried a lot of possibilities but couldn't find any solution. so i hope someone would help/educate me here.
Thanks a lot in advance!
If you have different components you must use in parrent component:
import Person from './Person';
ReactDOM.render(<Person name="Jon"/>, document.getElementById('main'));
and in child it must be smth like this:
import React, { Component } from 'react';
class Person extends Component {
constructor(props) {
super(props);
};
render() {
return(
<h1>Hi, {props.name}</h1>
);
}
export default Person;
you can pass by this way i don't know its correct but it worked for me
const test = {
myValue(props){
return props.yourValue
}
}

Home does not contain an export named Home

I was working with create-react-app and came across this issue where I get an error:
Home does not contain an export named Home.
Here's how I set up my App.js file:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { Home } from './layouts/Home'
class App extends Component {
render() {
return (
<div className="App">
Hello
<Home />
</div>
)
}
}
export default App;
Now in my layouts folder I have the Home.js file, which is setup like following:
import React, { Component } from 'react';
class Home extends Component {
render() {
return (
<p className="App-intro">
Hello Man
</p>
)
}
}
export default Home;
As you can see, I am exporting the Home component. But I get an error in my console saying this:
What is going on?
The error is telling you that you are importing incorrectly. Here's the code you have to add:
import { Home } from './layouts/Home';
This is incorrect because you're exporting as the default export, not as a named export. Check this line:
export default Home;
You're exporting as default, not as a name. Thus, import Home like this:
import Home from './layouts/Home';
Notice there are no curly brackets. Further reading on import and export.
Use
import Home from './layouts/Home'
rather than
import { Home } from './layouts/Home'
Remove {} from Home
This is a case where you mixed up default exports and named exports.
When dealing with the named exports, if you try to import them you should use curly braces as below,
import { Home } from './layouts/Home'; // if the Home is a named export
In your case the Home was exported as a default one. This is the one that will get imported from the module, when you don’t specify a certain name of a certain piece of code. When you import, and omit the curly braces, it will look for the default export in the module you’re importing from. So your import should be,
import Home from './layouts/Home'; // if the Home is a default export
Some references to look :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
https://medium.com/#trekinbami/a-not-so-in-depth-explanation-of-es6-modules-import-and-export-13a80300f2f0
I just ran into this error message (after upgrading to nextjs 9 some transpiled imports started giving this error). I managed to fix them using syntax like this:
import * as Home from './layouts/Home';
We also can use
import { Home } from './layouts/Home';
using export keyword before class keyword.
export class Home extends React.Component{
render(){
........
}
}
For default
import Home from './layouts/Home';
Default export class
export default class Home extends React.Component{
render(){
........
}
}
Both case don't need to write
export default Home;
after class.
put export { Home }; at the end of the Home.js file
Crazy as it may sound, i spent almost an hour to resolve a similar issue, restarted the localhost and it picked up by itself. Ridiculous but something restart fixes everything.
For me component in question was logout.
I imported like :
import {Logout} from './components';
with this define dint he Logout component
export default Logout
You can use two ways to resolve this problem, first way that i think it as best way is replace importing segment of your code with bellow one:
import Home from './layouts/Home'
or export your component without default which is called named export like this
import React, { Component } from 'react';
class Home extends Component{
render(){
return(
<p className="App-intro">
Hello Man
</p>
)
}
}
export {Home};
This is the solution:
Go to your file Home.js
Make sure you export your file like this in the end of the file:
export default Home;

Categories