How to separate routes from index.js in React - javascript

I am trying to separate my routes to a separate file using the following code in index.js:
import routes from './routes';
ReactDOM.render(
<Provider store={store}>
<Router routes={routes}/>
</Provider>
, document.getElementById('root')
);
my routes.js looks like this:
export default (
<Switch>
<Route exact path="/" component={AppComponent}/>
<Route exact path="/products" component={ProductContainer}/>
<Route path="/products/:productId" component={AddProductComponent}/>
</Switch>
);
For some reason my page appears blank with this code.
It works perfectly fine if I just wrap all routes inside index.js like this:
ReactDOM.render(
<Provider store={store}>
<Router>
<Switch>
<Route exact path="/" component={AppComponent}/>
<Route exact path="/products" component={ProductContainer}/>
<Route path="/products/:productId" component={AddProductComponent}/>
</Switch>
</Router>
</Provider>
, document.getElementById('root')
);
I would keep it like this, but I would also want to separate into a single file route handling.

Router is just a React component that allows for children prop. Render your routes as a component:
import Routes from './routes';
ReactDOM.render(
<Provider store={store}>
<Router>
<Routes />
</Router>
</Provider>
, document.getElementById('root')
);
Here a sample working codesandbox to play: https://codesandbox.io/s/ywvn59y7rj

More detailed answer, changing routes.js to
class Routes extends React.Component {
render() {
return (
<Switch>
<Route exact path="/" component={AppComponent}/>
<Route exact path="/products" component={ProductContainer}/>
<Route path="/products/:productId" component={AddProductComponent}/>
</Switch>
)
}
}
export default Routes;
and changing index.js to:
ReactDOM.render(
<Provider store={store}>
<Router>
<Routes/>
</Router>
</Provider>
, document.getElementById('root')
);
worked perfectly fine. I hope this would help anybody

Another option wich is easier to maintain is storing routes as JSON like objects in an array and then loop over them.
routes.js
import AppComponent from 'xxx'
export default const routes = [
{
path: '/',
component: AppComponent,
exact: true
}
// and so on
]
index.js
import routes from './routes';
ReactDOM.render(
<Provider store={store}>
<Router>
{routes.map({path, component, exact} => (
<Route exact={exact} path={path} component={component}/>
)}
</Router>
</Provider>
, document.getElementById('root')
);

Related

Why my components don't display on my React page?

So I'm learning React and building an app with multiple pages, I made a Routes file which looks like this:
import 'swiper/swiper.min.css';
import React from "react";
import { Route, Routes } from "react-router-dom";
import Home from "../pages/Home";
import Catalog from "../pages/Catalog";
import Detail from "../pages/Detail";
const Router = () => {
return (
<Routes>
<Route
path='/:category/search/:keyword'
component={Catalog}
/>
<Route
path='/:category/:id'
component={Detail}
/>
<Route
path='/:category'
component={Catalog}
/>
<Route
path='/'
exact
component={Home}
/>
</Routes>
);
}
And App.js looks like this:
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Header from './components/header/Header';
import Footer from './components/footer/Footer';
import Router from './config/Router';
function App() {
return (
<BrowserRouter>
<Routes>
<Route render={props =>{
<>
<Header {...props}/>
<Router/>
<Footer/>
</>
}}/>
</Routes>
</BrowserRouter>
);
}
export default App;
As you see, I have a browser router and Route which passes props to a component(as I understood) but for some reason the components don't display on the page(original components just have with their name inside of them, but they don't display in App.js).
And my console also says:
No routes matched location "/"
In routes.jsx file. I'm guessing it should lead to main page, but for some reason the route doesn't match and components in App.js don't display.
In Version 6.0.0 there is not any component prop in Route. It has been changed to element. So you need to change your Router to :
const Router = () => {
return (
<Routes>
<Route
path='/:category/search/:keyword'
element={Catalog}
/>
<Route
path='/:category/:id'
element={Detail}
/>
<Route
path='/:category'
element={Catalog}
/>
<Route
path='/'
exact
element={Home}
/>
</Routes>
);
}
As you've said you're using react-router-dom 6.0.2, and it seems that the tutorial you are following is for the older version (5?). There were some breaking changes in version 6.
You need to change your Router component to use element instead of component:
const Router = () => {
return (
<Routes>
<Route path="/:category/search/:keyword" element={<Catalog />} />
<Route path="/:category/:id" element={<Detail />} />
<Route path="/:category" element={<Catalog />} />
<Route path="/" exact element={<Home />} />
</Routes>
);
};
and also your App component seems to be getting in the way with the nested route.
I think it can be simplified to:
function App() {
return (
<BrowserRouter>
<>
<Header />
<Router />
<Footer />
</>
</BrowserRouter>
);
}
You can see a working demo on stackblitz

How to separate routes inside a React App

I have the following on my index.js
<Router routes={routes} />
I would like to have routes section in a separate file, so far I tried this:
routes.js
export default (
<div>
<Route path="/" component={AppComponent}>
<Route path="/someother" component={AddProductComponent} />
</Route>
<Route path="/products" component={ListProductComponent} />
</div>
);
and in index.js
import routes from './routes';
<Router routes={routes} />
For some reason the app shows blank now. looks like the routes are not rendered.
UPDATE, this is my whole index.js except missing imports due stackoverflow companing about too much code put:
const rootReducer = combineReducers({
products: productReducer,
});
const store = createStore(
rootReducer,
applyMiddleware(thunk),
);
ReactDOM.render(
<Provider store={store}>
<Router routes={routes} />
</Provider>
, document.getElementById('root')
);
Update routes.js
export default (
<Switch>
<Route exact path="/" component={AppComponent}/>
<Route path="/products" component={ListProductComponent}>
<Route path="/details/:productId" component={AddProductComponent} />
</Route>
</Switch>
);
You're missing the switch:
<Switch>
<Route path="/someother" component={AppComponent}>
<Route path="/products" component={ListProductComponent} />
<Route path="/" component={AppComponent}>
</Switch>
Also, your code will only show AppComponent, as any url (/, /home, /etc) starts with the slash you put in the path attribute. You might want that as a last page, a fallback.
The path attribute works with a wildcare: path="/" -> path="/**" are functionally the same. If you want an exact path, add exact to the Route.
If you mean to split routes into seperate files, you can do this:
<Switch>
<Route path={"/user"} component={UserRouter}/>
<Route path={"/product"} component={ProductRouter}/>
</Switch>
// In userRouter.jsx:
export function UserRouter() {
return <Switch>
<Route exact path={"/user/list"} component={UserListPage}/>
<Route exact path={"/user/signup"} component={userSignupPage}/>
<Route exact path={"/user/profile"} component={UserProfilePage}/>
</Switch>
};

React-Router 3 Error: <Route> elements are for router configuration only and should not be rendered

I try create SPA but I get the error. It works only with incorrect url for 404 page
Uncaught Error: elements are for router configuration only and should not be rendered
error screenshot
import React from 'react';
import { render } from 'react-dom'
import {Router, Route, browserHistory, IndexRoute} from 'react-router';
import { Provider } from 'react-redux'
import configureStore from './store/configureStore'
import Full from './containers/Full/'
import LoginPage from './containers/LoginPage/'
import Page404 from './views/Pages/Page404/'
import Dashboard from './views/Dashboard/';
const store = configureStore()
ReactDOM.render((
<Provider store={store}>
<Router history={browserHistory}>
<div>
<Route path="/" component={Full}>
<IndexRoute component={Dashboard} />
<Route path='dashboard' component={Dashboard} />
<Route path='login' component={LoginPage} />
</Route>
<Route path='*' component={Page404} />
</div>
</Router>
</Provider>
), document.getElementById('root'));
Try this:
const store = configureStore()
const routes = (
<Route path="/" component={Full}>
<IndexRoute component={Dashboard} />
<Route path='dashboard' component={Dashboard} />
<Route path='login' component={LoginPage} />
<Route path='*' component={Page404} />
</Route>
);
const App = (
<Provider store={store}>
<Router history={browserHistory} routes={routes} />
</Provider>
)
ReactDOM.render(App, document.getElementById('root'));

Redux & React-router : Provider bug

I'm starting new app using ReactJS. All the web env is quite new for me.
Anyway, I created an simple App, using react-router. Works perfectly :).
I tried to add Redux, and ... fail. I have no idea how use React-redux AND react-router.
Here's my input JS : index.js
class App extends React.Component{
render(){
return(
<div>
{routes}
</div>
);
}
}
ReactDOM.render(
<Provider store={store}> <App /> </Provider>,
document.getElementById('app')
);
Here's my route.js
export default (
<Router history={hashHistory}>
<Route path='/' component={Main}>
<IndexRoute component={Home} />
<Route path='playerOne' header="PlayerOne" component={PromptContainer} />
<Route path='playerTwo/:playerOne' header="PlayerTwo" component={PromptContainer} />
<Route path='battle' component={ConfirmBattleContainer} />
<Route path='results' component={ResultsContainer} />
<Route path='maninthemiddle' component={ManinthemiddleContainer} />
<Route path='button' component={ButtonContainer} />
</Route>
</Router>
);
and ofc my reducer.js
import reducer from './reducer.js'
import { createStore } from 'redux';
const store = createStore(reducer);
export default store;
And this is my error.
Uncaught Error: React.Children.only expected to receive a single React element > child
and my warning :
Warning: Failed prop type: Invalid prop children of type array supplied > > to Provider, expected a single ReactElement.
I know that Provider have to be on "top" of the app, but it's exactly what I did. I'm lost :(
Thanks for your helps guys.
You need to remove the whitespace around <App />. This:
ReactDOM.render(
<Provider store={store}> <App /> </Provider>,
document.getElementById('app')
);
should be:
ReactDOM.render(
<Provider store={store}><App /></Provider>,
document.getElementById('app')
);
the spaces in there are being treated as text nodes, i.e. additional children.

React.js Route not working properly

my / route doesn't properly render my main component.
Her is my code:
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" componenet={Main}>
<IndexRoute component={Index}></IndexRoute>
<Route path="portfolio" component={Portfolio}></Route>
</Route>
</Router>,
document.getElementById('app')
);
This is my Main component:
export default class Main extends React.Component {
render() {
console.log("asdfasfsaf");
return(
<div>
<h1> This is Main Page </h1>
{this.props.children}
</div>
)
}
}
Once i load the website it doesn't console log anything nor render <h1> This is main page header. Also If I delete this Main componenet it still goes to my IndexRoute without any error which is my index componenet.
Try this:
ReactDOM.render((
<Router history={browserHistory}>
<Route path="/" componenet={Main}>
<IndexRoute component={Index}></IndexRoute>
<Route path="portfolio" component={Portfolio}></Route>
</Route>
</Router>,
), document.getElementById('app'));

Categories

Resources