Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Router only one child

I keep on getting the error:

A 'Router' may have only one child element

when using react-router.

I can't seem to figure out why this is not working, since it's exactly like the code they show in their example: Quick Start

Here is my code:

import React from 'react';
import Editorstore from './Editorstore';
import App from './components/editor/App';
import BaseLayer from './components/baselayer';
import {BrowserRouter as Router, Route} from 'react-router-dom';
import {render} from 'react-dom';

const root = document.createElement('div');
root.id = 'app';
document.body.appendChild(root);

const store = new Editorstore();
const stylelist = ['https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css', 'https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.2/semantic.min.css', 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css', 'https://api.tiles.mapbox.com/mapbox-gl-js/v0.33.1/mapbox-gl.css'];

stylelist.map((link) => {
    const a = document.createElement('link');
    a.rel = 'stylesheet';
    a.href = link;
    document.body.appendChild(a);
    return null;
});

render((
  <Router>
    <Route exact  path="/" component={BaseLayer} />
    <Route path="/editor" component={App} store={store} />
  </Router>
), document.querySelector('#app'));
like image 965
Mar Avatar asked Mar 24 '17 06:03

Mar


People also ask

Why you get router may have only one child element warning?

Generally, navigation in a React-based environment is used over the whole application. That is why React components like BrowserRouter or Router expect that only the top-level component that is <App> should be enclosed within them. Hence, they cannot work when multiple routes are listed within them as children.

Is React router and React router Dom same?

They are technically three different packages: React Router, React Router DOM, and React Router Native. The primary difference between them lies in their usage. React Router DOM is for web applications and React Router Native is for mobile applications made with React Native.

Why use React router Dom?

React Router DOM enables you to implement dynamic routing in a web app. Unlike the traditional routing architecture in which the routing is handled in a configuration outside of a running app, React Router DOM facilitates component-based routing according to the needs of the app and platform.

How many types of Routers are there in React?

On the basis of the part of URL that the router will use to track the content that the user is trying to view, React Router provides three different kinds of routers: Memory Router. Browser Router. Hash Router.


Video Answer


4 Answers

You have to wrap your Route's in a <div>(or a <Switch>).

render((
  <Router>
    <Route exact  path="/" component={BaseLayer} />
    <Route path="/editor" component={App} store={store} />
  </Router>
), document.querySelector('#app'));

should be

render((
  <Router>
    <div>
       <Route exact  path="/" component={BaseLayer} />
       <Route path="/editor" component={App} store={store} />
    </div>
  </Router>
), document.querySelector('#app'));

jsfiddle / webpackbin

like image 56
QoP Avatar answered Oct 09 '22 01:10

QoP


This is an API change in react-router 4.x. Recommended approach is to wrap Routes in a Switch: https://github.com/ReactTraining/react-router/issues/4131#issuecomment-274171357

Quoting:

Convert

<Router>
  <Route ...>
  <Route ...>
</Router>

to

<Router>
  <Switch>
    <Route ...>
    <Route ...>
  </Switch>
</Router>

You will, of course, need to add Switch to your imports:

import { Switch, Router, Route } from 'react-router'
like image 45
FeifanZ Avatar answered Oct 09 '22 03:10

FeifanZ


I Always use Fragment in react web and native ( >= react 16 )

import React, { Component, Fragment } from 'react'
import { NativeRouter as Routes, Route, Link } from 'react-router-native'
import Navigation from './components/navigation'    
import HomeScreen from './screens/home'
import { RecipesScreen } from './screens/recipe'

class Main extends Component {
  render() {
    return (
      <Fragment>
        <Navigation />
        <Routes>
          <Fragment>
            <Route exact path="/" component={HomeScreen} />
            <Route path="/recipes" component={RecipesScreen} />
          </Fragment>
        </Routes>
      </Fragment>
    )
  }
}

export default Main
like image 3
White Rabbit Avatar answered Oct 09 '22 03:10

White Rabbit


I put all my <Route /> tags inside the <Switch> </Switch> tag like this.

    <BrowserRouter>
        <Switch>
            <Route path='/' component={App} exact={true} /> 
            <Route path='/form-example' component={FormExample} />
        </Switch>
    </BrowserRouter>

This solves the problem.

like image 2
Vishal Shetty Avatar answered Oct 09 '22 01:10

Vishal Shetty