I have upgraded to React Router V4 and now struggling with the history.push method.
I have an index.js file:
import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Route } from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
const history = createBrowserHistory();
import { Main} from "./components/Main";
import { About } from "./components/About";
import { Cars} from "./components/Cars";
class App extends React.Component {
render() {
return (
<BrowserRouter history={history}>
<div>
<Route path={"/"} component={Main} />
<Route path={"/cars"} component={Cars}/>
<Route path={"/about"} component={About}/>
</div>
</BrowserRouter>
)
}
}
render(<App/>, window.document.getElementById("app"));
And then I have another file, where I added a simple to return to a certain page which looks like this:
import React from "react";
import createBrowserHistory from 'history/createBrowserHistory';
const history = createBrowserHistory();
export class Cars extends React.Component {
navigateBack() {
history.push('/')
}
render() {
return(
<div>
<h3>Overview of Cars</h3>
<p>Model: </p>
<button onClick={this.navigateBack} className="btn btn-primary">Back</button>
</div>
)
}
}
So, I cannot figure out whats going wrong here. When I click on the button, the URL changes to / but thats all. Is there someone who can help me out?
EDIT
I found out, that it works when I do this:
this.props.history.push('/home')
and
<button onClick={this.onNavigateHome.bind(this)}
but it seems wrong somehow??
when I do
this.context.history.push('/home')
I get Cannot read property 'context' of null but why?? Is my <BrowserRouter> setup wrong??
Anyway, thanks for the help :)
You have to import {withRouter} from 'react-router-dom' and export your class in this way
export default withRouter(Cars)
Try adding forceRefresh={true} to your BrowserRouter.
<BrowserRouter forceRefresh={true}>
With v4 you have to use this.context.history.push('/cart');
check out these posts for more insights:
How to push to History in React Router v4?
history.push not working when using BrowserRouter
Try to use history from props and ensure that your export is wrapped with withRouter.
Ex:
this.props.history.push('/test')
export default withRouter(TestComponent)
Related
Please help me get this minimum-working example with withNavigation to work
https://codesandbox.io/s/withnavigation-not-working-lds560?file=/src/index.js
import React, {Component} from "react";
import {withNavigation, NavigationInjectedProps} from "react-navigation";
class App extends Component<NavigationInjectedProps> {
render() {
return <h1>Hello CodeSandbox</h1>;
}
}
export default withNavigation(App);
I found a little hacky-solution in which you create your own custom withNavigation. (I am still looking for a solution to make it work without having to create your own custom withNavigation function)
App.tsx
import React, {Component} from "react";
import {useNavigate, NavigateFunction} from "react-router-dom";
class App extends Component<{navigate: NavigateFunction, text: string}> {
render() {
return <button onClick={() => this.props.navigate("/c")}>
We are at path: {this.props.text}, navigate to "/c"
</button>;
}
}
function withNavigation(Component: any): (props: any) => JSX.Element {
return props => <Component {...props} navigate={useNavigate()} />;
}
export default withNavigation(App);
index.js
import * as ReactDOMClient from "react-dom/client";
import {Route, Routes, BrowserRouter } from "react-router-dom";
import App from "./App";
const rootElement = document.getElementById("root");
const root = ReactDOMClient.createRoot(rootElement);
root.render(
<BrowserRouter>
<Routes>
<Route path="/a" element={<App text={"a"}/>}/>
<Route path="/b" element={<App text={"b"}/>}/>
</Routes>
</BrowserRouter>
);
You need to move your
import {withNavigation, NavigationInjectedProps} from "react-navigation"
to a separate file which you have to include in App and wrap in in <Navigation Container>.
See here
Update:
I’ve just seen that you are trying to work with react-navigation 4! This probably won’t work with my solution but considering that version 4^ is no longer maintained, you might think about updating to version 5^.
I have a Nutrition facts button on my page that when clicked can route to another page on my site that lists the nutrition facts. How do I make this happen?
Basically you need to use react-router-dom package and make use of BrowserRouter and Route and Switch and define your routes.
Then you need wrap your button with Link and indicate where to route to.
Your app component
import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import NutritionPage from "./components/NutritionPage";
import NutritionFacts from "./components/NutritionFacts";
function App() {
return (
<Router>
<Switch>
<Route path='/' exact component={NutritionPage}></Route>
<Route path='/nutrition-facts' component={NutritionFacts}></Route>
</Switch>
</Router>
);
}
export default App;
NutritionPage Component
import React from 'react';
import {Link} from "react-router-dom";
const NutritionPage = (props) => {
return (<div>
<h2>My Nutrition Page</h2>
<Link to='/nutrition-facts'><button>Nutrition Facts</button></Link>
</div>)
};
export default NutritionPage;
NutritionFacts Component
import React from 'react';
const NutritionFacts = (props) => {
return (<div>Nutrition Facts List Page</div>)
};
export default NutritionFacts;
For more details and examples read the docs
I am trying to get my react component to render in Meteor. I don't see any error messages or anything in the console, however, the component doesn't seem to display.
I am using react-router. I added log statements and it appears that the renderRoutes() function does get called, also, I see errors in the console when I change the directories for my imports (I get an error if I change the first import statement to import {Home} from '../home/blah'). I am not really sure what to try next.
Here is my router, which is in client/imports/lib/router.js.
import React from 'react';
import { Router, Route, Switch } from 'react-router';
import {createBrowserHistory} from 'history';
import {Home} from '../home/home';
import {Login} from '../login/login';
import {Connect} from '../connect/connect';
const browserHistory = createBrowserHistory();
export const renderRoutes = () => (
<Router history={browserHistory}>
<Switch>
<Route exact path="/" component={Home}/>
<Route exact path="/login" component={Login}/>
<Route exact path="/connect" component={Connect}/>
</Switch>
</Router>
);
Here is my home page. The other pages have a similar structure. The home page is in client/imports/home/home.js.
import React, { Component } from 'react';
export default class Home extends Component {
constructor(){
super()
this.state = {
}
}
render() {
return (
<div><h1>hello from the home page</h1></div>
);
}
}
Finally, this is my main.js. It's in client/main.js.
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';
import { renderRoutes } from './imports/lib/router.js';
import './main.html';
Meteor.startup(() => {
render(renderRoutes(), document.getElementById('app'));
});
Again, I don't see any error messages. The home page just doesn't render. I put console.log's in the constructor for the Home component and I do not see anything. I'm not sure if there is something about React that I am not understanding or if I need to change the way I am using the router.
Please let me know what I should try next, and if there is any more information I should include.
Thanks!
If you're exporting component using export default
export default class Home extends Component {
then you should import it this way:
import Home from '../home/home';
Read more about named and default exports
For the future - back to the source, check original code (from docs) first (usually working) - it's not hard to see the difference ;)
I'm trying to add routes to my react project. I have three separate components:
Window.js
import React, { Component } from 'react';
import SideBar from "../SideBar/SideBar";
import MainBody from "../MainBody/MainBody";
import { BrowserRouter as Router} from "react-router-dom";
class Window extends Component{
render() {
return (
<div>
<Router>
<SideBar />
<MainBody />
</Router>
</div>
);
}
}
export default Window
SideBar.js
import React, { Component } from 'react';
import PropTypes from "prop-types";
import { BrowserRouter as Link} from "react-router-dom";
class SideBar extends Component {
render() {
return(
<Link to="/">Home</Link>
<Link to="/about">About</Link>
);
}
}
export default SideBar;
MainBody.js
import React, { Component } from 'react';
import Home from "./Home/Home";
import About from "./About/About";
import { BrowserRouter as Route} from "react-router-dom";
class MainBody extends component {
render() {
return(
<div>
<Route exact path="/" component={Home}>
<Route path="/about" component={About}>
</div>
);
}
}
export default MainBody;
So basically, when I click one of my links in SideBar, I want to transition to that link in my Main Body (the Home and About just display their titles). However, When I run this, my Window, MainBody, and SideBar components work but my Home and About components do not get displayed. I've properly imported the router components into each component file. If I place the Routes from MainBody into the Window component, they get displayed (Not sure if the router links work with it though). Any suggestions would be helpful!
There are few typos in that snippets, dunno ifit was made when rewriting or u have it in your codebase, but be careful about them (component instead of Component, wrongly writtern render function with multiple elements returned etc).
import { BrowserRouter as Link} from "react-router-dom";
Theese imports are also wrong, You have to import Link not something as Link. You are only renaming import BrowserRouter to Link.
import { Link } from "react-router-dom";
And same for Route.
Here is example codesanbox . Let me know if that is what you wanted.
I came across the site https://hashnode.com/. When we click any topic it updates the URL and content without refreshing the site.
I know we can update the content using states and props without refresh.
How to change the URL at the same time?
Image
That's what React Router is for.
Routes.js
import React from 'react';
import {BrowserRouter,Switch,Route, withRouter} from 'react-router-dom';
import FirstPage from './pages/FirstPage';
import SecondPage from './pages/SecondPage';
class Routes extends React.Component {
render() {
return(
<Switch>
<Route exact path="/page-1" component={FirstPage} />
<Route exact path="/page-2" component={SecondPage} />
</Switch>
)
}
}
App.js
import React from 'react';
import store from "./Store";
import { Provider } from 'react-redux';
import Routes from "./Routes";
import {BrowserRouter} from 'react-router-dom';
class App extends React.Component
{
render()
{
return (
<Provider store={store}>
<BrowserRouter>
<Routes/>
</BrowserRouter>
</Provider>
)
}
}
export default App;