React - Render more than one Component - javascript

I have the typical index.js that calls App.js
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(
<App />,
document.getElementById('root')
);
App.js
import './App.css';
import Test from './Components/test'
import Test1 from './Components/test1'
function App() {
return (
<Test/>,
<Test1/>
);
}
export default App;
When building App.js i wanted to render 2 components Test and Test1
When i run this code only one of the components gets rendered. In this case only Test1 is rendered. If i switch the order only Test is rendered
Is there any way that i can render 2 components?

You can only render one component, so an approach would be to wrap them in one. For example, in a React Fragment, like so:
import { Fragment } from 'react'
...
return (
<Fragment>
<Test />
<Test1 />
</Fragment>
)
Fragment is just a wrapper, it doesn't provide any functionality. Alternatively, you can wrap your components like so:
return (
<>
<Test />
<Test1 />
</>
)
The result would be the same.

You need to wrap this Test and Test1 into some wrap
import './App.css';
import Test from './Components/test'
import Test1 from './Components/test1'
function App() {
return (
<div>
<Test/>,
<Test1/>
</div>
);
}
export default App;

try this
function App() {
return (
<>
<Test />
<Test1 />
</>
)
}

Related

ReactJs not rendering anything on page

I've been working with the react router dom and I keep seeing a blank white page on my screen.
App.js:
import React from 'react';
import HelloWorld from './HelloWorld';
import { HashRouter as Router, Route } from 'react-router-dom';
import Home from './Home';
function App() {
return (
<Router>
<Home />
<Route path="/notes" exact element={HelloWorld} />
</Router>
);
}
export default App;
Home.js:
import React from 'react';
import { Link } from 'react-router-dom';
function Home() {
return (
<div>
<Link to="/testHome" style={{ color: 'blue', fontSize: '20px' }}>
Go to Notes
</Link>
</div>
);
}
export default Home;
HelloWorld.js:
import React from 'react';
function MyComponent() {
return (
<div>
<h1>Hello world</h1>
</div>
);
}
export default MyComponent;
Index.js:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
When I simply display the components in app.js, I can clearly see the hello world element on the screen, the problem is when I use react router. When I use react router I just see a blank white page. Can anyone help me solve the issue?
There are a couple issues:
The Route component isn't being rendered by a Routes (or other Route component in the case of nested routes).
The element prop takes a React.ReactNode prop value, a.k.a. JSX.
To resolve import the Routes component and wrap the Route component and render the HelloWorld component as JSX.
import React from 'react';
import HelloWorld from './HelloWorld';
import {
HashRouter as Router,
Routes, // <-- import Routes
Route
} from 'react-router-dom';
import Home from './Home';
function App() {
return (
<Router>
<Home />
<Routes> // <-- wrap rendered routes
<Route
path="/notes"
element={<HelloWorld />} // <-- render as JSX
/>
</Routes>
</Router>
);
}

Why is my component not loading through Vite

I am building a React project with Vite. I was using a tutorial from an article that I found at https://www.digitalocean.com/community/tutorials/how-to-set-up-a-react-project-with-vite.
I followed the tutorial as described, however, my "greeting" component will not load.
import React from 'react';
function greeting() {
return (
<div>
Hello World!
</div>
);
}
export default greeting;
import React from 'react';
import greeting from "./greeting";
function App() {
return (
<main>
React⚛️ + Vite⚡ + Replit🌀
<greeting />
</main>
);
}
export default App;
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
const container = document.getElementById("root");
const root = createRoot(container);
root.render(
<StrictMode>
<App />
</StrictMode>
);
Components should start with capital letter .
import React from 'react';
function Greeting() {
return (
<div>
Hello World!
</div>
);
}
export default Greeting;
import React from 'react';
import Greeting from "./greeting";
function App() {
return (
<main>
React⚛️ + Vite⚡ + Replit🌀
<Greeting />
</main>
);
}
export default App;
React components have to start with a capital letter, or they will be compiled to a plain HTML tag.
See https://reactjs.org/docs/jsx-in-depth.html#user-defined-components-must-be-capitalized
So your greeting function should be named Greeting, and change the tag in App() to <Greeting />
your component import name should use Capital Letter
ex : import Greeting from "./greeting";

React jest - You should not use <Link> outside a <Router>

I have a super simple react app like so.
index.tsx
App.tsx
Main.tsx
Home.tsx
index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter as Router } from "react-router-dom";
import { ApolloProvider } from "react-apollo";
import client from "./utils/client";
ReactDOM.render(
<Router>
<ApolloProvider client={client}>
<App />
</ApolloProvider>
</Router>,
document.getElementById('root')
);
App.tsx
import React from 'react';
import Main from "./Main";
function App() {
return (
<Main />
);
}
export default App;
Main.tsx
import React from 'react';
import { Switch, Route, Link } from "react-router-dom";
import Home from "./Home";
const Main:React.FC = () => {
return (
<div>
<Switch>
<Route exact path='/' component={Home} />
</Switch>
</div>
);
};
export default Main;
Home.tsx
import React, {useContext} from 'react';
import { Link } from "react-router-dom";
const Home:React.FC = () => {
return (
<div>
<h1>Home</h1>
<Link to='http://google.com'> Google</Link>
</div>
);
};
export default Home;
I have an App.test.tsx with a dummy test just to run it.
import React from 'react';
import { render, screen } from '#testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
expect(true).toBeTruthy
});
If I run the test with yarn test
I get an error:
Invariant failed: You should not use <Link> outside a <Router>
The Link I have is in Home.tsc which is surrounded by <Router> in index.tsx
I'm I doing something work here.
The app runs without any errors.
This error only appears when I run the test
There are two solutions below, the first is to add <Router> component into your test case. The second option is to switch from <Link> to a simple anchor tag.
Option 1:
You can add <Router> component into your test also, so it won't missing there as:
test('renders learn react link', () => {
render(<Router>
<App />
</Router>);
expect(true).toBeTruthy
});
Option 2:
Also you can change from <Link> component to a simple anchor tag because it creates the same end result based on your code from:
<Link to='http://google.com'> Google</Link>
To the following in <Home> component:
Google
Then at the end you can keep your original test case.

Problem with exporting/importing React component

I'm trying to create a React component for a navigation bar.
This component I'd like to import from a separate file into my App.js.
Currently, the component should just return a simple 'Hello world' paragraph, but I have trouble getting this to work.
I have written the following code into a file located at src/components/navbar.js:
import React from 'react';
export default class navBar extends React.Component {
render() {
return (
<p>Hello world.</p>
)
}
}
Now I'd like to import this component from my src/App.js, which looks like this:
import React, { Component } from 'react';
import './App.css';
import navBar from './components/navbar.js'
class App extends Component {
render() {
return (
<navBar/>
);
}
}
export default App;
If I compile and open the site, nothing's there, which confuses me.
I'd be very thankful for any help!
EDIT:
It's been suggested that the problem is that <App /> is not being rendered anywhere. I don't believe that's the case, since there's another file being created by default (index.js), which looks like this:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();
I have also tried putting the paragraph (and the entire navbar) directly into src/App.js.
After compiling I could see the expected results in the browser, so the problem should lie with the exporting/importing.
In JSX, lower case tags are considered to be simple HTML/SVG elements. You can use lower case only if you use accessors (so with a dot like bla.blabla).
You can read about it here for example.
So in your case you must change the class name navBar to NavBar and then in the render method:
render() {
return (
<NavBar/>
);
}
Here is a full working example:
** Note: NavBar.js shoud start with a Capital letter.
App.js
import React from "react";
import ReactDOM from "react-dom";
import NavBar from "./components/NavBar";
function App() {
return (
<div className="App">
<NavBar />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
NavBar.js
import React from "react";
export default class NavBar extends React.Component {
render() {
return (
<div>
<p>Hello world.</p>
</div>
);
}
}

Additional component in <MuiThemeProvider /> results in blank page w/ no error messages

I have recently installed Material UI into my Meteor application using npm install --save material ui
I have gotten the <Header /> component showing up in my app.js file, but whenever I add other components, localhost:3000 simply displays a blank page. Please see my code below:
header.js
import React, { Component } from 'react';
import AppBar from 'material-ui/AppBar';
class Header extends Component {
render() {
return(
<AppBar
title="Header"
titleStyle={{textAlign: "center"}}
showMenuIconButton={false}
/>
);
}
}
export default Header;
app.js
import React from 'react';
import ReactDOM from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Header from './components/header';
import NewPost from './components/new_post';
const App = () => {
return (
<MuiThemeProvider>
<Header />
</MuiThemeProvider>
);
};
Meteor.startup(() => {
ReactDOM.render(<App />, document.querySelector('.render-target'));
});
THE ABOVE CODE WORKS WELL (see screenshot below)
However, if I add another component I get a blank screen
header.js is the same
new_post.js
import React, { Component } from 'react';
import TextField from 'material-ui/TextField';
class NewPost extends Component {
render() {
return (
<TextField
hintText="Full width"
fullWidth={true}
/>
);
}
}
export default NewPost;
app.js
import React from 'react';
import ReactDOM from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Header from './components/header';
import NewPost from './components/new_post';
const App = () => {
return (
<MuiThemeProvider>
<Header />
<NewPost />
</MuiThemeProvider>
);
};
Meteor.startup(() => {
ReactDOM.render(<App />, document.querySelector('.render-target'));
});
The result is simply a blank screen
Why does adding one more component (<NewPost />)inside of <MuiThemeProvider> result in a blank screen? I referred to the material-ui documentation and their sample projects but their application structure is not similar to mine. Any advice? Please let me know if you need more info to make this question clearer.
Wow very strange but I managed to get it working by simply adding a <div>
app.js
const App = () => {
return (
<MuiThemeProvider muiTheme={getMuiTheme()}>
<div>
<Header />
<NewPost />
</div>
</MuiThemeProvider>
);
}
Meteor.startup(() => {
ReactDOM.render(<App />, document.querySelector('.render-target'));
});
I would really appreciate if anyone could explain why adding a div makes this all work. Thank you!
I would really appreciate if anyone could explain why adding a div
makes this all work
If you look at the browser warning, "Invalid prop children of type array supplied to MuiThemeProvider, expected a single ReactElement.".
So, when you add a <div/> around your components, it wraps them together and turns them into a single react element.
MuiThemeProvider renders as null so you have to wrap children do anything - for example React.Fragment

Categories