I have a Main component that looks like this:
import React from 'react';
import { Provider } from 'react-redux';
import { Router, Route } from 'react-router-dom';
import store from '../store';
import history from '../store/history';
import SideBar from './SideBar';
import { ConnectedUsers } from './UsersPage';
const Main = () => (
<Router history={history}>
<Provider store={store}>
<div>
<SideBar/>
<Route
exact
path="/users"
render={ () => (<ConnectedUsers/>)}
/>
</div>
</Provider>
</Router>
);
export default Main;
It uses a navigation component which I've named SideBar:
import { Link } from 'react-router-dom';
import React from 'react';
const SideBar = () => (
<div>
<Link to="/users">
<h1>Users</h1>
</Link>
</div>
);
export default SideBar;
This doesn't work. When I click on the Users link on the page in the browser, the URL changes to the correct one (localhost:8080/users) but the page remains blank. The component doesn't render. If I put the URL localhost:8080/users manually in the address bar in the browser the component renders correctly.
After some searches, I found people recommending to implement the routes like this:
import React from 'react';
import { Provider } from 'react-redux';
import { Router, Route, withRouter } from 'react-router-dom';
import store from '../store';
import history from '../store/history';
import SideBar from './SideBar';
import { ConnectedUsers } from './UsersPage';
const Main = () => (
<Router history={history}>
<Provider store={store}>
<div>
<SideBar/>
<Route exact path="/users" component={withRouter(ConnectedUsers)}
/>
</div>
</Provider>
</Router>
);
export default Main;
But this also didn't work for me. The exact same propblem remains—the /users page renders correctly when I manually type in the URL in the address bar, but comes up blank if I navigate to that URL using the Link.
Related
I am fairly new to using react and been following a couple of tutorials on YT, I have ran into a problem with one of them. I copied everything line by line, but my text on 'Home' and 'Login' doesnt display! I get no errors, but the page remains blank.
here is App.js
import React from 'react'
import { Routes, Route, useNavigate } from 'react-router-dom';
import Login from './components/Login';
import Home from './container/Home';
const App = () => {
return (
<Routes>
<Route path="login" element={<Login />} />
<Route path="/*" element={<Home />} />
</Routes>
);
};
export default App;
Also the index.js file:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';
import './index.css';
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById('root'),
);
**Then Login.jsx
**
import React from 'react';
const Login = () => {
return (
<div>
Login
</div>
);
};
export default Login;
Finally Home.jsx
import React from 'react';``your text``
const Home = () => {
return (
<div>
Home
</div>
);
};
export default Home;
I know I am missing something, but I cant seem to find it! Any and all help is very much appreciated!
Tried to see if I am using on old version of the BroswerROuter/Routes in React, but I have very little knowledge to see the difference just yet!
I am tried to make a chat room application with react js,
but I have faced a problem when I tried to see just chatroom page then it's ok, but when I refresh the page then again show me the home page that mean show me both page in the chatroom page, I don't know why show me home page again,
I have tried this way:
import React from "react";
import { Router, Route } from "react-router-dom";
import HomePage from "./HomePage";
import TopBar from "./TopBar";
import { createBrowserHistory as createHistory } from "history";
import "./App.css";
import ChatRoomPage from "./ChatRoomPage";
const history = createHistory();
function App() {
console.log("Working");
return (
<div className="App">
<Router history={history}>
<TopBar />
<Route path="/:chatRoomId" component={HomePage} />
<Route
path="/chatroom"
exact
render={(props) => <ChatRoomPage {...props} />}
/>
</Router>
</div>
);
}
export default App;
any suggestion please.
You should use react router dom exact way
like: import { BrowswerRouter as Router, Route, Switch } from "react-router-dom";
then take upper the render router.
import React from "react";
import { BrowswerRouter as Router, Route, Switch } from "react-router-dom";
import HomePage from "./HomePage";
import TopBar from "./TopBar";
import { createBrowserHistory as createHistory } from "history";
import "./App.css";
import ChatRoomPage from "./ChatRoomPage";
const history = createHistory();
function App() {
console.log("Working");
return (
<div className="App">
<Router history={history}>
<TopBar />
<Switch>
<Route
path="/chatroom"
exact
render={(props) => <ChatRoomPage {...props} />}
/>
<Route path="/:chatRoomId" component={HomePage} />
</Switch>
</Router>
</div>
);
}
export default App;
I have tried to decouple my components a bit more and I ran into this weird bug. I obscured the other general imports. All components import properly and work.
What happens is I land on "/", then I click a button to navigate to dashboard it's a blank page (the URL did change). Then I hit refresh in my browser and the correct component displays. This also happens if I go back to my landing page; it's blank until I refresh.
In my app component
import history from './services/history';
import Routes from './routes';
function App() {
return (
<Router history={history}>
<Routes />
</Router>
);
my history component (super simple)
import { createBrowserHistory} from 'history';
const history = createBrowserHistory();
export default history;
and finally my routes:
import Landing from "../pages/landing/landing.page"
import Dashboard from "../pages/dashboard/dashboard.page.jsx"
export default function Routes() {
return (
<Switch>
<Route path="/" exact component={Landing}/>
<Route path="/dashboard" component={Dashboard}/>
</Switch>
);
Here is my landing page, which I click the button to navigate to "/dashboard"
import { Link } from "react-router-dom";
function Landing () {
return (
<div class="landing-container">
<Link to="/dashboard"><button> Setup Tests </button></Link>
</div>
)
}
export default Landing;
It looks like you're now using Router from react-router-dom. From my understanding, you have to import BrowserRouter in terms of browser use. So your code would look like:
import { BrowserRouter } from "react-router-dom";
function App() {
return (
<BrowserRouter history={history}>
<Routes />
</Router>
);
}
I'm trying to build a simple example project where the user is redirected to the 'contact' page upon clicking a button, using React. I'm trying to achieve this by setting the value of a state property. When I run the code I have, it does change the browser address bar URL to that of the contact page, but does not seem to actually load the component - I get a blank page instead. If I manually navigate to that URL (http://localhost:3000/contact) I can see the contents.
Here are my App.js and Contact.js files -
App.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route, Link, Redirect } from 'react-router-dom';
import Contact from './Contact';
class App extends Component {
state = {
redirect: false
}
setRedirect = () => {
this.setState({
redirect: true
})
}
renderRedirect = () => {
if (this.state.redirect) {
return <Redirect to='/contact' />
}
}
render() {
return (
<Router>
<Switch>
<Route exact path='/contact' component={Contact} />
</Switch>
<div>
{this.renderRedirect()}
<button onClick={this.setRedirect}>Redirect</button>
</div>
</Router>
)
}
}
export default App;
Contact.js
import React, { Component } from 'react';
class Contact extends Component {
render() {
return (
<div>
<h2>Contact Me</h2>
<input type="text"></input>
</div>
);
}
}
export default Contact;
Using state isn't really a requirement for me, so other (preferably simpler) methods of redirection would be appreciated too.
Since your button is nothing more than a link, you could replace it with:
<Link to="/contact">Redirect</Link>
There are many alternatives though, you could for example look into BrowserRouter's browserHistory:
import { browserHistory } from 'react-router'
browserHistory.push("/contact")
Or perhaps this.props.history.push("/contact").
There are pros and cons to every method, you'll have to look into each and see which you prefer.
I got here for a similiar situation. It's possible use withRouter (https://reactrouter.com/web/api/withRouter) to handle that.
This example was tested with "react": "^16.13.1","react-router-dom": "^5.2.0" and "history": "^5.0.0" into "dependecies" sections in package.json file.
In App.js I have the BrowserRouter (usually people import BrowserRouter as Router, I prefer work with original names) with Home and Contact.
App.js
import React, { Component } from "react";
import {
BrowserRouter,
Switch,
Route,
} from "react-router-dom";
import Home from "./pages/Home";
import Contact from "./pages/Contact";
class App extends Component
{
// stuff...
render()
{
return (
<BrowserRouter>
<Switch>
<Route path="/contact">
<Contact />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</BrowserRouter>
);
}
}
export default App;
ASIDE 1: The Route with path="/contact" is placed before path="/" because Switch render the first match, so put Home at the end. If you have path="/something" and path="/something/:id" place the more specific route (with /:id in this case) before. (https://reactrouter.com/web/api/Switch)
ASIDE 2: I'm using class component but I believe (I didn't test it) a functional component will also work.
In Home.js and Contact.js I use withRouter associated with export keyword. This makes Home and Contact components receive the history object of BrowserRouter via props. Use method push() to add "/contact" and "/" to the history stack. (https://reactrouter.com/web/api/history).
Home.js
import React from "react";
import {
withRouter
} from "react-router-dom";
export const Home = ( props ) =>
{
return (
<div>
Home!
<button
onClick={ () => props.history.push( "/contact" ) }
>
Get in Touch
<button>
</div>
);
}
export default withRouter( Home );
Contact.js
import React from "react";
import {
withRouter
} from "react-router-dom";
export const Contact = ( props ) =>
{
return (
<div>
Contact!
<button
onClick={ () => props.history.push( "/" ) }
>
Go Home
<button>
</div>
);
}
export default withRouter( Contact );
Particularly, I'm using also in a BackButton component with goBack() to navigate backwards:
BackButton.js
import React from "react";
import {
withRouter
} from "react-router-dom";
export const BackButton = ( props ) =>
{
return (
<button
onClick={ () => props.history.goBack() }
>
Go back
<button>
);
}
export default withRouter( BackButton );
So I could modify the Contact to:
Contact.js (with BackButton)
import React from "react";
import BackButton from "../components/BackButton";
export const Contact = ( props ) =>
{
return (
<div>
Contact!
<BackButton />
</div>
);
}
export default Contact; // now I'm not using history in this file.
// the navigation responsability is inside BackButton component.
Above was the best solution for me. Other possible solutions are:
useHistory Hook (https://reactrouter.com/web/api/Hooks)
work with Router instead BrowserRouter - (https://reactrouter.com/web/api/Router)
First off, I have read through just about every example I can find and looked through various boilerplates to see how others have done this. I am having issues loading pages when clicking <Link>'s with react-router v4. I have also installed the package react-router-connected and have been trying that out as well but no improvement can be seen (however it shows the changes in the redux-logger which is nice).
Currently, the url updates just fine and if I manually change the url and press enter, then the next page will load. But, it will not redirect if I click a link. I am also using create-react app for the project, just for your reference. My actual app is setup as the exact example from usage with react-router in the official redux docs. For simplicity, I have changed my routes to only include links to basic components that do nothing but redirect to one another.
Root.js which houses my routes
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'connected-react-router'
// import App from './App';
import NewComponent from './NewComponent';
import OldComponentent from './OldComponent';
const Root = ({ store, history }) => (
<Provider store={store}>
<ConnectedRouter history={history}>
<Router>
<Switch>
<Route exact path='/' component={OldComponentent}/>
<Route path='/new' component={NewComponent}/>
{/* <Route path='/' component={App}/>
<Route path='/:filter' component={App}/> */}
</Switch>
</Router>
</ConnectedRouter>
</Provider>
)
export default Root;
Home component
import React from 'react';
import { connect } from 'react-redux';
import { push } from 'connected-react-router';
import { withRouter } from 'react-router';
import { Link } from 'react-router-dom';
import Button from 'material-ui/Button';
class OldComponent extends React.Component {
redirectPage = () => { this.props.dispatch(push('/new')); };
redirectPage1 = () => { this.props.dispatch(push('/')); };
render() {
return (
<div>
OLD COMPONENT
<Button onClick={this.redirectPage}>Redirect new</Button>
<Button onClick={this.redirectPage1}>Redirect /</Button>
<Link to='/new'>Redirect Link</Link>
</div>
)
}
}
export default withRouter(connect()(OldComponent));
Other basic component for redirection purposes
import React from 'react';
import { connect } from 'react-redux';
import { push } from 'connected-react-router';
import { withRouter } from 'react-router';
import { Link } from 'react-router-dom';
import Button from 'material-ui/Button';
class NewComponent extends React.Component {
redirectPage = () => { this.props.dispatch(push('/')); };
redirectPage1 = () => { this.props.dispatch(push('/new')); };
render() {
return (
<div>
NEW COMPONENT
<Button onClick={this.redirectPage}>Redirect /</Button>
<Button onClick={this.redirectPage1}>Redirect new</Button>
<Link to='/new'>Redirect Link</Link>
</div>
)
}
}
export default withRouter(connect()(NewComponent));
As you can see, they are essentially the same component with minor differences. The url will change to /new or / and will also update the pathname found in the ##router/LOCATION-CHANGE state objects created by react-router-connected package. The url will also change by clicking the <Link> tag but with no redirect.
Any help on how to approach this would be greatly appreciated.
The comment posted by #Supertopoz works this.props.history.push('/pathname') works. However, after setting that up, the <Link> now works as well. I am also using withRouter (which I was before) throughout, so that was another important factor in egtting it to work.