Error is: A <Router> may have only one child element - javascript

I have problem in React.js when I save the code the website page say:
A <Router> may have only one child element
What is the problem and how can I solve it?
import React, { Component } from 'react';
import Head from './component/head';
import Contacts from './component/contacts';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import Addcontacts from './component/Addcontacts';
import { Provider } from "./context";
import 'bootstrap/dist/css/bootstrap.min.css';
class App extends Component {
render() {
return (
<Provider>
<Router>
<Head promo = 'alow' />
<div className='container'>
<Switch>
<Route exact path='/' Component={Contacts} />
<Route exact path='/add' Component={Addcontacts} />
</Switch>
</div>
</Router>
</Provider>
);
}
}
export default App;

you can use React.Fragment https://reactjs.org/docs/fragments.html#short-syntax to fix this issue.
<Router>
<>
<Head promo = 'alow' />
<div className='container'>
<Switch>
<Route exact path='/' Component={Contacts} />
<Route exact path='/add' Component={Addcontacts} />
</Switch>
</div>
</>
</Router>
So basically you just need to have a single tag in you compenent as a child.

Inside your <Router> wrap everything in a single <div> like this
<Router>
<div>
// all your content
</div>
</Router>

Router expect this.props.children to be null or to have length equal to 1
In your case its more than 1
So if you wrap all attr. inside a single tag it should work fine
You can use any of these
<> => React.Fragment
<div> => DIV
Eg:
class App extends Component {
render() {
return (
<Provider>
<Router>
<div>
<Head promo = 'alow' />
<div className='container'>
<Switch>
<Route exact path='/' Component={Contacts} />
<Route exact path='/add' Component={Addcontacts} />
</Switch>
</div>
</div>
</Router>
</Provider>
);
}
}

Related

Component is not getting renderend properly with react-router

function App() {
return (
//BEM naming convention
<div className="app">
<div className="app__body">
<Sidebar />
<Chat />
<Router>
<Routes>
<Route exact path="/arroz" element={<MainPage />} />
</Routes>
</Router>
</div>
</div>
);
}
export default App;
can someone explain me why when i inicialize app, its rendering as supposed to and when i try to render the same thing but with the components inside this one component, it looses the css i have done and only uses a small part of screen. also when i render the page, it should only render the component, but instead is also rendering code that shouldnt be read.
how its being rendered
how it should be rendering
import React from "react";
import Chat from "./Chat";
import Sidebar from "./Sidebar";
function MainPage() {
return (
<div className="mainPage">
<Sidebar />
<Chat />
</div>
);
}
export default MainPage;
obs: i didnt styled MainPage.css and as i was inspecting the page the compenent had "display:block" dont know the meaning
i have done this and this works as i want, still i would like to understand why is not taking the form its suposed to
function App() {
return (
//BEM naming convention
<div className="app">
<div className="app__body">
<Sidebar />
<Router>
<Routes>
<Route exact path="/rooms/:roomId" element={<Chat />} />
</Routes>
</Router>
</div>
</div>
);
}
export default App;
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
it seems if i put this on indeex and change the app like this it works has it suposed to
function App() {
return (
//BEM naming convention
<div className="app">
<div className="app__body">
<Sidebar />
<Routes>
<Route exact path="/rooms/:roomId" element={<Chat />} />
</Routes>
</div>
</div>
);
}
export default App;

routing in react issues

i am trying to create a basic web page in react which has some <h1> text and two links - one to login page and other to register page. here is the code->
index.js
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
App.js
import './App.css';
import Header from './components/register/header';
import RegistrationForm from './components/register/registrationForm'
import { Route, Link, BrowserRouter as Router } from 'react-router-dom';
function App() {
return (
<div className="App">
<br></br>
<h1>Welcome to my website!</h1>
<br></br>
<br></br>
<br></br>
<Link to="/register">Register</Link>
<Route exact path="/register" component={RegistrationForm} />
</div>
);
}
export default App;
what i want is when i click on register button, i want the Header and RegistrationForm component to load and App component to disappear.
This code is not working. i get an empty screen.
if i remove these lines
<Link to="/register">Register</Link>
<Route exact path="/register" component={RegistrationForm} />
the App component works fine. can someone help?
---EDIT---
App.js
import "./App.css";
import Header from "./components/register/header";
import RegistrationForm from "./components/register/registrationForm";
import Home from "./components/home/home";
import { Routes, Route, Link } from "react-router-dom";
function App() {
return (
<div className="App">
<Home />
<Link to="/register">Register</Link>
<Routes>
<Route
path="/register"
element={
<>
<Header />
<RegistrationForm />
</>
}
/>
</Routes>
</div>
);
}
export default App;
Home.js
import React from "react";
function Home() {
return (
<div>
<br></br>
<h1>Welcome to my website!</h1>
<br></br>
<br></br>
<br></br>
</div>
);
}
export default Home;
//end
Router, Switch and Header are missing.
You need something like this :
import { BrowserRouter as Router } from 'react-router-dom';
render(
<Router>
<App />
</Router>,
document.getElementById('root')
);
<div className="App">
<Switch>
<Route exact path="/">
<Home/>
</Route>
<Route exact path="/register">
<Header />
<RegistrationForm/>
</Route>
</Switch>
</div>
<div className="Home">
<br />
<h1>Welcome to my website!</h1>
<br />
<br />
<br />
<Link to="/register">Register</Link>
</div>
I think you will need to make a second Switch like this to share your header between pages except Home :
<div className="App">
<Switch>
<Route exact path="/">
<Home/>
</Route>
<Route path="/">
<Header />
<Switch>
<Route exact path="/register">
<RegistrationForm/>
</Route>
{/* Other routes with the Header */}
</Switch>
</Route>
</Switch>
</div>
App.js
import "./App.css";
import Header from "./components/register/header";
import RegistrationForm from "./components/register/registrationForm";
import Home from "./components/home/home";
import { Routes, Route, Link } from "react-router-dom";
function App() {
return (
<div className="App">
<Routes>
<Route exact path="/" element={<Home />} />
<Route
path="/register"
element={
<>
<Header />
<RegistrationForm />
</>
}
/>
</Routes>
</div>
);
}
export default App;
you should wrap the app with Router :
import { BrowserRouter as Router } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Router>
<App />
</Router>
</React.StrictMode>
);
and in App.js you are missing Routes wrapping Route:
import { Routes, Route, Link } from 'react-router-dom';
function App {
*other code*
<Routes>
<Route path="/" component={Home} />
<Route path="/register" component={RegistrationForm} />
</Routes>
}

React routing to endpoint but not rendering content

I can route to another endpoint, but the component content only appears on manual refresh.
I've seen this question asked here, here, and I've been checking out the reactrouter docs, amongst others. The solution always seems to be "add withRouter" or "make sure you're wrapping it in Router. I've done those things, but sadly got no where.
Here's the code:
App.js
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
function App() {
return (
<Router>
<Provider store={store}>
<div className="App">
<NavBar />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/account" component={Account} />
</Switch>
</div>
</Provider>
</Router>
);
}
NavBar.js
import { BrowserRouter as Router, Link } from "react-router-dom";
import { withRouter } from "react-router";
function NavBar() {
return (
<Router>
<div className="navbar">
<h3>Connectory</h3>
<div className="buttons-container">
<Link>
<button>Settings</button>
</Link>
<Link to="/account"> // successfully redirects to /account, but doesn't render Account page content until refresh
<button>Account</button>
</Link>
</div>
</div>
</Router>
);
}
export default withRouter(NavBar);
EDIT: After comment suggestions, here's a code sandbox link and here;s the Account.js page:
import React from "react";
export default function Account() {
return (
<div>
<h3>This is the Account page</h3>
</div>
);
}
The Problem here is that, in your Navbar.js, you are re-setting your Routes again when they are already set in App.js.
<Switch>
<Route exact path="/" component={Home} />
<Route path="/account" component={Account} /> // Route for Applicatin set here
</Switch>
You do not need to do that again in. Check here.
https://codesandbox.io/s/gracious-germain-7fyry?file=/src/Navbar.js
Your Nabar should look like:
function NavBar() {
return (
<div className="navbar">
<h3>Connectory</h3>
<div className="buttons-container">
<Link to="/">
<button>Settings</button>
</Link>
<Link to="/account">
<button>Account</button>
</Link>
</div>
</div>
);
}
Hi i found a bug in your code and that's the reason because is not working.
in this component you are injecting the Router to the rest of the app.
function App() {
return (
<Router>
<div className="App">
<NavBar />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/account" component={Account} />
</Switch>
</div>
</Router>
);
}
in this one you are injecting again the Router. That's why is not working you just have to remove the Router from de Navbar and it will work properly.
function NavBar() {
return (
<Router>
<div className="navbar">
<h3>Connectory</h3>
<div className="buttons-container">
<Link>
<button>Settings</button>
</Link>
<Link to="/account">
<button>Account</button>
</Link>
</div>
</div>
</Router>
);
}
like this
function NavBar() {
return (
<div className="navbar">
<h3>Connectory</h3>
<div className="buttons-container">
<Link>
<button>Settings</button>
</Link>
<Link to="/account">
<button>Account</button>
</Link>
</div>
</div>
);
}

Using Header globally in react using react-router-dom

I am currently using react-router-dom to create navigation within my web app.
My index.js and App.js look like:
Index.js
ReactDOM.render(
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>,
document.getElementById('root')
);
App.js
class App extends React.Component {
render() {
return (
<BrowserRouter>
<div>
<Route exact path ='/' component={Home} />
<Route path ='/container' component={Container} />
<Route path ='/profile' component={ProfilePage} />
</div>
</BrowserRouter>
);
}
}
I idea was that if Home contains the header and the sidebar, it would also keep it for other components like Container and ProfilePage.
My Home's render looks like:
render() {
return (
<div>
<Header />
<div className="App">
<Sidebar />
<Container className="container-comp" />
{this.renderLoggingOutput()}
</div>
</div>
);
}
But when I Link to /profile, it just shows me the ProfilePage component without the header and the sidebar.
Any help?
Put your header outside the routes:
class App extends React.Component {
render() {
return (
<BrowserRouter>
<Header /> <-------- place here or outside the routes at a minimum
<div>
<Route exact path ='/' component={Home} />
<Route path ='/container' component={Container} />
<Route path ='/profile' component={ProfilePage} />
</div>
</BrowserRouter>
);
}
}
I have a similar structure in one of my apps.
the routes look like this:
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="App">
<Navbar />
<Switch>
<Route exact path='/' component={Dashboard}/>
<Route path='/character/:id' component={CharacterDetails}/>
<Route path='/encounter/:id' component={Encounter}/>
.........
</Switch>
</div>
</BrowserRouter>
);
}
}
export default App;
The only job of a route is to mount a component. If you want omnipresent components across all routes, treat the routes as children to a base component.
class App extends React.Component {
render() {
<div>
<Header />
<Sidebar />
{this.props.children}
</div>
}
}
const Routes = () => (
<App>
{/* your routes here */}
</App>
)

React-router v4 updates url but doesn't render component

I'm using react-router v4, no redux. The code example is below:
class MainPage extends Component {
render() {
return (
<div className="MainPage">
<BrowserRouter>
<Switch>
{/* <Route exact path='/' /> */}
<Route path='/signin' component={SignIn}/>
<Route path='/signup' component={SignUp} />
<Redirect from='*' to='/' />
</Switch>
</BrowserRouter>
</div>
);
}
}
When I'm using Link it updates URL in browser but doesn't render anything, nothing happens. When I resfresh, everything becomes fine and component renderes;
export default class Navbar extends Component {
render() {
return (
<div className="navbar">
<BrowserRouter>
<div>
<Link to='/signin'>Sign in</Link>
<Link to='/signup'>Sign up</Link>
</div>
</BrowserRouter>
</div>
);
}
}
I already tried everything, even withRouter(Component), but it says that with router may only be used inside
How can I deal with this?
Here is the working code. As others explained you should use one BrowserRouter. If you want to render your Navbar component all the time then you should place it above Switch but under BrowserRouter hence you need Link there.
const Navbar = () => (
<div className="navbar">
<Link to='/signin'>Sign in</Link>
<Link to='/signup'>Sign up</Link>
</div>
);
class MainPage extends React.Component {
render() {
return (
<div className="MainPage">
<BrowserRouter>
<div>
<Navbar />
<Switch>
{/* <Route exact path='/' /> */}
<Route path='/signin' component={SignIn} />
<Route path='/signup' component={SignUp} />
<Redirect from='*' to='/' />
</Switch>
</div>
</BrowserRouter>
</div>
);
}
}
You should only have a single BrowserRouter component in your tree. The BrowserRouter component holds the shared state the router used to synchronize the URL with the rendered routes. In your situation, you are getting two different versions of router state because you rendering two BrowserRouter components so you should probably render a single BrowserRouter component somewhere higher in your component tree.
If you have an App component that renders both Navbar and MainPage then you can move the router into that component:
export default class App extends Component {
render() {
return (
<BrowserRouter>
<div className="AppContainer">
<Navbar />
<MainPage />
</div>
</BrowserRouter>
);
}
}

Categories

Resources