Reputation: 1253
I'm having an issue of when I click a link in the navbar that's in the header, instead of the component loading below, the whole page changes (and is blank. No error is visibly thrown, but not even the component that's supposed to render on that route shows up.
I'll explain how this site setup works.
const initialState = {};
const history = createHistory();
const store = configureStore(initialState, history);
const MOUNT_NODE = document.getElementById('app');
const render = (messages) => {
ReactDOM.render(
<Provider store={store}>
<LanguageProvider messages={messages}>
<ConnectedRouter history={history}>
<Switch>
<Route exact path="/" component={Splash} />
<Route path="/main" component={App} />
</Switch>
</ConnectedRouter>
</LanguageProvider>
</Provider>,
MOUNT_NODE
);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
When a user first enters the site, they see the splash page. Then they click a button that gets them to the main homepage. Here's the code for that:
const AppWrapper = styled.div`
max-width: calc(768px + 16px * 2);
margin: 0 auto;
display: flex;
min-height: 100%;
padding: 0 16px;
flex-direction: column;
`;
class App extends React.Component {
render() {
return (
<div>
<Header />
<AppWrapper>
Below this are where the new components should render.
<Switch>
<Route path="/aboutme" component={AboutMe} />
<Route path="/models" component={Models} />
<Route path="/landscapes" component={Landscapes} />
</Switch>
<Footer />
</AppWrapper>
</div>
);
}
}
export default App;
As you can see I'd like the header to remain on top regardless of what component is selected by the route.
The header's navbar looks like this:
class NavBar extends React.Component {
render() {
return (
<div>
<AppBar position="static" color="default" >
<Toolbar>
<Typography type="title" color="inherit">
<Link to="/models">Models</Link>
</Typography>
<Typography type="title" color="inherit">
<Link to="/landscapes">Adventures</Link>
</Typography>
<Typography type="title" color="inherit">
<Link to="/aboutme">About Me</Link>
</Typography>
</Toolbar>
</AppBar>
</div>
);
}
}
export default NavBar;
When I click a link here, the route in the address bar changes appropriately, but a blank page shows up without even the header/toolbar. Does anyone have any ideas on what I'm doing wrong here? I'm trying to use a react/redux boilerplate and am still learning.
Upvotes: 0
Views: 1972
Reputation: 895
You are mapping route /main
to App
component, and the route /models
,/landscapes
, /aboutme
is rendered inside the App
component, so your routes look like this:
See the problem? A route can never match both the /main
and /models
,... at the same time. So those routes never got rendered.
Change the route of App
component to /
(not exact match), so the code in the index.js
will look like this:
...
<ConnectedRouter history={history}>
<Switch>
<Route exact path="/" component={Splash} />
<Route path="/" component={App} />
</Switch>
</ConnectedRouter>
...
The react-router
's Switch
will use the first route to match with the current route (e.g. https://mywebsite.com/path/to/some/where
). A route is match if the URL begin with the path value (e.g. /
, /models
,...), with /
character at the begin indicate the root of the website (so /models
is equivalent to https://mywebsite.com/models
, this is called short absolute path).
So, when you are in https://mywebsite.com/models
, react-router
matching the path /models
with the routes:
/
exact route`: not match because exact route requires the route to be exactly the same/main
route: not match, /models
not start with /main
Then the react-router
renders nothing because no route is match.
When you change /main
to /
, the result will be like this:
/
exact route`: not match/
route: match, every path match with /
(with strict
option default to false
)The router then renders the App
component, then, in the inner switch:
/aboutme
route: not match,/models
route: match, renders the Models
component and skip the following routes.Upvotes: 1
Reputation: 171
When you update the route with NavBar component, the new route (ex: /models) will not be caught in your render of the MOUNT_NODE.
The routes handled by MOUNT_NODE are only “/“ and “/main”. Which is why any route besides them renders a blank page.
To make it work in your situation you would have to make all the Links in the NavBar begin with “/main” and the routes in the App component match.
Here is some good info on react-router v4. CSS-Tricks React Router 4
Upvotes: 1
Reputation: 184
This is how i set it up to work for me. Using React-router v4
my index file
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App.jsx';
import 'bootstrap/dist/css/bootstrap.css';
import registerServiceWorker from './registerServiceWorker';
import 'font-awesome/css/font-awesome.min.css';
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import appReducer from './containers/reducers/index.js';
const store = createStore(appReducer, applyMiddleware(thunk));
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('app'));
registerServiceWorker();
store.subscribe(() => {
console.log("Store Changed, ", store.getState());
});
my App file where i setup my routes
import React, { Component } from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import Splash from './containers/home/Home.jsx';
import Model from './containers/home/About.jsx';
export default class Routes extends Component{
render(){
return (
<BrowserRouter>
<div>
<Header />
<Switch>
<Route exact path="/" component={Splash} />
<Route path="/models" component={Models} />
<Route path="/landscapes" component={Landscapes} />
</Switch>
<Footer />
</div>
</BrowserRouter>
)
}
}
<Typography type="title" color="inherit">
<Link to={"/models"} >Models</Link>
</Typography>
NOTE: There is a <Header />
Component and a <Footer />
component. I did this becasue my header and footer are constant through out my app.
This should work, just follow the basic and edit to work for you.
Upvotes: 0