I'm stuck creating a single page app using react, redux, react-router and react-redux-router bindings.
The route http://localhost:3001/register is simply not matched by the router and Cannot GET /register is returned to the browser because the server obviously doesn't know the route. I'm relatively new to the react-redux stack and may be missing something pretty basic.
Edit: The IndexRoute is working and is displaying the Home-Component inside the App-Compontent.
Edit2: I'm not using server side rendering and am developing using the webpack-dev-server.
But here are the related code-snippets so far:
entry.js
const store = createStore(
reducer, //from reducers.js
applyMiddleware(routerMiddleware(browserHistory))
);
const history = syncHistoryWithStore(browserHistory, store);
render(
<Provider store={store}>
<Router history={history} routes={routes} /> //routes from routes.js
</Provider>,
document.getElementById('app')
);
reducers.js
const rootReducer = combineReducers({
RegisterForm,
routing: routerReducer //provided by react-router-redux
});
export default rootReducer;
routes.js
const routes = (
<Route path='/' component={App}>
<IndexRoute component={Home} />
<Route name='register' path='register' component={RegisterForm} />
</Route>
);
export default routes;
Navigation.jsx (rendered inside App.jsx)
import React from 'react';
import {Link} from 'react-router';
export default class Navigation extends React.Component {
render() {
return (
<div className="mdl-layout mdl-js-layout mdl-layout--fixed-header">
<header className="mdl-layout__header">
<div className="mdl-layout__header-row">
<span className="mdl-layout-title">there!</span>
<div className="mdl-layout-spacer"></div>
<nav className="mdl-navigation mdl-layout--large-screen-only">
<Link className="mdl-navigation__link" to="/">Home</Link>
<Link className="mdl-navigation__link" to="register">Register</Link>
</nav>
</div>
</header>
<div className="mdl-layout__drawer">
<span className="mdl-layout-title">there!</span>
<nav className="mdl-navigation">
<Link className="mdl-navigation__link" to="/">Home</Link>
<Link className="mdl-navigation__link" to="register">Register</Link>
</nav>
</div>
<main className="mdl-layout__content">
<div className="page-content">
{this.props.children}
</div>
</main>
</div>
);
}
}
Maybe it is obvious to someone, what I am missing here. If you need more of the code please let me know.
As you say, the problem is that your backend does not know how to handle requests to /register. The solution is to tell your backend to return the react application (same as requests to /) on such requests.
If you are developing with pure webpack-dev-server I'm not 100% sure what's the best way to do this, but you can take a look at the answer here which will probably work: Stating directive templateUrl relative to root
You can use hashHistory instead of browserHistory. It's written in react-router's documentation.
Of course, you will need to configure the Link's to props so it will redirect properly according to the needs of hashHistory. Later on, when you are back using browserHistory, you need to reconfigure those links again.
Related
I know this question has been asked plenty of times. But sadly after implementing all of the possible solutions I still get a blank browser page after using Route, Routes.
My Code:
import { Container } from 'react-bootstrap'
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Header from './components/Header'
import Footer from './components/Footer'
import HomeScreen from './screens/HomeScreen'
function App() {
return (
<Router>
<Routes>
<Header />
<main className="py-5">
<Container>
<Route path='/' component={<HomeScreen/>} />
</Container>
</main>
<Footer/>
</Routes>
</Router>
);
}
export default App;
Thank You for for help!
Issues
In react-router-dom#6 the Route components can only be rendered directly by the Routes component or another Route component in the case of route nesting.
The Route component API also changed significantly. There are no longer any component or render and children function props. They are replaced by a single element prop taking a React.ReactNode, a.k.a. JSX.
Solution
Move the Routes component down the tree to directly wrap the Route component(s), and switch to using the element prop to pass the routed content.
function App() {
return (
<Router>
<Header />
<main className="py-5">
<Container>
<Routes>
<Route path='/' element={<HomeScreen />} />
</Routes>
</Container>
</main>
<Footer/>
</Router>
);
}
I think you shouldn't nest elements other than <Route> inside <Routes> component. When location changes, <Routes> looks on all of his <Route> children and choose the one that fits. You nested your <Route> element inside <Header> so probably that's the problem. Try to rearrange the structure and move Routes to the top level.
When a user goes to my domain www.example.com they see my webpage I created using React. I want to use React to show them a different webpage when they go to www.example.com/anotherpage instead.
This is the code I have in my index.js file which creates the webpage at www.example.com,
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
There are multiple solution for this, if you are creating an SPA with create-react-app, then one of the most popular solution is by using react-router.
As shown in the example, then the basic routing is like this:
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
export default function App() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
</ul>
</nav>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return <h2>Route Home</h2>;
}
function About() {
return <h2>Route About</h2>;
}
function Users() {
return <h2>Route Users</h2>;
}
However if you are using another framework such as Next.js, then they have the filesystem pages where creating a page under /pages/ folder will create a new route.
You need to use React Router for this purpose and declare separate routes for pages you want access to.
npm install react-router-dom
afterward, you can create separate components for the specific routes and attach them to the Routes as seen below,
import { BrowserRouter as Router,Route,Switch} from 'react-router-dom'
const Home = () => <h1>hello world!</h1>
const AnotherPage = () => <div>Another page!</div>
const App = () => {
<Router>
<Switch>
<Route path="/" component={Home}/>
<Route path="/anotherpage" component={AnotherPage}
</Switch>
</Router>
}
export default App;
You can look at the documentation for more examples react-router Quickstart
you should use npm install react-router-dom with nested routing for a better approach
I want to connect my sidebar to dashboard. Everytime I click on an icon in the sidebar I want to sidebar to stays the same but dashboard to change. https://imgur.com/1hwNlNr I am having a problem with the rendering. When I click on the Sound Icon Sidebar does not stay as you can see https://imgur.com/YjLmhLh
import React from 'react'
import './SystemSidebar.css'
import SoundIcon from '#material-ui/icons/Computer';
import ComputerIcon from '#material-ui/icons/Computer';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';
import Sound from './Sound';
import Computer from './Computer;
const SystemSidebar=()=> {
return (
<div className='system'>
<div className="sidebar">
<Link to='Sound'><VolumeUpIcon /></Link>
<h4> Sound</h4>
<Link to='Computer'><ComputerIcon /></Link>
<h4> Computer</h4>
</div>
</div>
import React,{Component} from 'react'
import Sound from './Sound';
import Computer from './Computer';
import SystemSidebar from './SystemSidebar';
class MainSystem extends Component {
render(){
return (
<div className="MAIN">
<BrowserRouter>
<SystemSidebar />
<Switch>
<Route exact path="/" component={SystemSidebar} />
<Route exact path="/Sound" component={Sound}/>
<Route exact path="/Computer" component={Computer}/>
</Switch>
</BrowserRouter>
</div>
);
}
}
Did you post the code from two separate .js files into this code block? Your SystemSidebar function is missing some closing parenthesis/brackets and this code has multiple duplicate imports/incorrect paths if all this code lives in the same file.
Other than that, you're rendering SystemSidebar twice when at the root URL. You want a component for some type of home/welcome page at this route, not the sidebar:
<Route exact path="/" component={SystemSidebar} />
Please post complete code in separate code blocks if the code is in separate files.
I am trying to understand basics of reach router and have doubts on following code
import React from "react";
import { render } from "react-dom";
import Logo from "./Logo";
import { Router, Link } from "#reach/router";
let Home = () => (
<div>
<h1>Home</h1>
<nav>
<Link to="/">Home</Link> |{" "}
<Link to="/dashboard">Dashboard</Link>
</nav>
</div>
)
let Dash = () => <div>Dash</div>
render(<Router>
<Home path="/" />
<Dash path="dashboard" />
</Router>, document.getElementById("root"));
I know that this Router works as Switch from router 4, i.e., renders only one path inside router.
Now when I start the app initially I am inside Home, e.g. here
<div>
<h1>Home</h1>
<nav>
<Link to="/">Home</Link> |{" "}
<Link to="/dashboard">Dashboard</Link>
</nav>
</div>
At this moment it is my belief that Dashboard component hasn't been rendered anywhere. However, if I type dashboard in URL or click the above link it correctly takes me to Dashboard component.
My question is how does algorithm of resolving to Dashboard works in this case?
Does it "restart" the app and see that there was a component registered for "dashboard" route initially?
My point is because when I am at home location there is nothing on the page anymore that indicates that Dashboard component is registered under dashboard route, or I am wrong?
<Router>'s internal implementation uses history.listen() (https://github.com/reach/router/blob/master/src/index.js#L103) which in turn listens to native popstate events (https://developer.mozilla.org/en-US/docs/Web/Events/popstate). You can see it in action here.
It looks like your intuitions are indeed right. <Router> component is history-aware by listening to history changes. It re-renders routes as a result of internal setState calls.
I can recommend going though the source code if you'd like to know even more about implementation details.
So I am very new to React and react routing so forgive me if this is simple. I have seen similar questions asked but not quite what I was looking for or I didnt understand it enough to figure it out.
Question: How do I get routing to jump to the page? It changes in the URL but seemingly no change. (localhost:8080/#/listings?_k=26kljm) is the same as localhost:8080/
Anyway here is what I have
main.js
import React from "react";
import ReactDOM from "react-dom";
import { Router, Route, IndexRoute, hashHistory } from "react-router";
import Layout from "./components/Layout";
import Listing from "./components/pages/Listings";
import NoMatch from "./components/partials/NoMatch";
const app = document.getElementById('app');
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={Layout}>
<Route path="/listings" name="listings" component={Listing}></Route>
</Route>
</Router>,
app);
Layout.js
import React from "react";
import Footer from "./partials/Footer";
import Body from "./pages/Index";
import Header from "./partials/Header";
export default class Layout extends React.Component {
render() {
return (
<div>
<Header/>
<Body />
<Footer />
</div>
);
}
}
Header.js
This one is long so ill spare you but you should know there is a link
<Link to="/listings">Listings</Link>
And finally
Listings.js
import React from "react";
import Header from "../partials/Header";
import Footer from "../partials/Footer";
export default class Listings extends React.Component {
render(){
return(
<div>
<Header />
<div class="row">
<div class="col-md-8">
<h1>THIS SHOULD BE HERE</h1>
</div>
</div>
<Footer />
</div>
);
}
}
I feel like I am missing something small or I dont have a good grasp on components.
To Note: I just noticed in the source the Link created an href like this
Listings
Why is the extra hash there!?
I get a Cannot GET /listings if I go directly to localhost:8080/listings
At first sight, I cannot find any mistake in your code. But I would recommend you to check out the react router examples which will fit perfect to your case:
https://github.com/reactjs/react-router
Just clone this repo, run npm install and npm start. Then you can browse through the examples within the URL http:localhost:8080.
When you take a look at the "Active Links" example, you will notice that it shows exactly what you want (except HashHistory, but you can add this manually without much work).
Hope this helps.
Many greetings
So the problem was with how I was understanding components.
The key here is {this.props.children}
By changing Layout.js too:
export default class Layout extends React.Component {
render() {
return (
<div>
<Header/>
{this.props.children}
<Footer />
</div>
);
}
}
main.js
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={Layout}>
<IndexRoute component={Index}></IndexRoute>
<Route path="/listings" name="listings" component={Listing}></Route>
</Route>
</Router>,
app);
The makes routing work correctly