I have a react component which is loaded on routing
I need to access a parameter from the url inside the components constructor
How do I do it?
can I access it like this:
class CustomCoponent extends React.Component {
constructor(props,{match}) {
}
}
You can access route parameter in react-router-dom v4.x, by getting params from the match props.
Where you define your routes,
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
...
<Router>
<App>
<Switch>
<Route exact path="/" component={List} />
<Route path="/:parameterToAccess" component={CustomComponent} />
</Switch>
</App>
</Router>
...
In your component,
class CustomComponent extends React.Component {
constructor(props) {
super(props);
this.routeParam = props.match.params.parameterToAccess;
}
}
if you use routing then you can specify your route to expect the parameter.
<Route path='/yourpath/:ParamName' component={CustomComponent}/>
your component needs to be wrapped in the withRouter HOC for you to access this.
import {withRouter} from 'react-router-dom';
class CustomComponent extends React.Component{
constructor(props){
}
//**ACCESS PARAMETER VALUE LIKE THIS**
sample(){
let Paramvalue=this.props.match.params.ParamName;
}
}
export default withRouter(CustomComponent);
You can do it like this:
class CustomComponent extends React.Component {
constructor({ match, ...props }) {
console.log(match.params)
}
}
As {match} is passed to the component as a prop(property) so we can access this prop as a normal prop way.
class CustomComponent extends React.Component {
console.log(this.props.match.url)
}
Routes
import logo from './logo.svg';
import './App.css';
import {BrowserRouter as Router,Route,Switch} from 'react-router-dom';
import UpdateEmployeeComponent from './components/UpdateEmployeeComponent';
function App() {
return (
<div>
<Router>
<div className="container">
<Switch>
<Route path="/update-employee/:id" component={UpdateEmployeeComponent}></Route>
</Switch>
</div>
</Router>
</div>
);
}
export default App;
Component
import React, { Component } from 'react';
class UpdateEmployeeComponent extends Component {
constructor(props){
super(props);
this.state ={
id : this.props.match.params.id
}
console.log('Employee Id ::: '+this.id);
}
render() {
return (
<div>
</div>
);
}
}
export default UpdateEmployeeComponent;
Related
I am attempting to pass data via react-router-dom, specifically I wanted to hold state data in the App.js file which I am using to route to different pages. I can't get the props to pass. What am I doing off here? Below is an example of what I am trying to do:
App.js
import React, { Component } from 'react';
import Home from './Home';
import {BrowserRouter as Router, Route,Switch, withRouter } from 'react-router-dom';
class App extends Component {
constructor(props) {
super(props);
this.state = {
testProps:7
}
}
render() {
return (
<Router>
<div>
<Route
exact path="/"
component = {Home}
render={(props) => <Home testProps={this.state.testProps} {...props} />}/>
</div>
</Router>
);
}
}
export default App;
Home.js
import React, { Component } from 'react';
class Home extends Component {
render() {
return (
<div>
{`passing props from state: ${this.props.testProps}`}
</div>
);
}
}
export default Home;
In my home page I see: passing props from state: undefined. Am I approaching this incorrectly?
I am using React and have my project structured in a way that I have layout components and then the main page components. I want to change the title of the page in the header component depending on which route the user came to.
Here is my App.jsx:
import React, { Suspense, lazy, Component } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Header from './layout/Header.jsx';
import Footer from './layout/Footer.jsx';
const Home = lazy(() => import('./pages/Home.jsx'));
const Weather = lazy(() => import('.pages/Weather.jsx'));
const Encryption = lazy(() => import('./pages/Encryption.jsx'));
const Video = lazy(() => import('./pages/Video.jsx'));
class App extends Component {
render() {
return (
<Router>
<>
<Header/>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/weather" component={Weather}/>
<Route path="/encryption" component={Encryption}/>
<Route path="/video" component={Video}/>
</Switch>
</Suspense>
<Footer/>
</>
</Router>
);
}
}
export default App;
My Header.jsx component is like so:
import React, { Component } from 'react';
class Header extends Component {
constructor(props) {
super(props);
}
render() {
return (
<h1>Page Title</h1>
);
}
}
export default Header;
import React, { Component } from "react";
import { withRouter } from "react-router-dom";
class Header extends Component {
constructor(props) {
super(props);
}
render() {
const path = this.props.location.pathname.slice(1);
return (
<div>
<h1>{path}</h1>
</div>
);
}
}
export default withRouter(Header);
Working example here: https://codesandbox.io/s/zl3y72k0pp
thre HOC withRouter will provide the props match, location and history to your component.
then your can use location.pathname to manage the rendering of your component
I have a app created from create-react-app and the prop location for all my components is always undefined..
Here is index.js
ReactDOM.render((
<BrowserRouter >
<App/>
</BrowserRouter>
), document.getElementById('root'));
registerServiceWorker();
Here is a short version of app.js
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
auth: UserProfile.getAuth(),
}
}
render() {
if(this.state.auth){
return (
<Router>
<Switch>
...
<Route path="/editUser" render={()=><EditUser className="App" app={this}/>} />
</Switch>
</Router>
);
}
else{
...
}
}
}
now here is editUser.jsx
class EditUser extends React.Component {
constructor(props) {
super(props);
...
}
componentDidMount(){
console.log(this.props.location) //undefined
}
render() {
return (<div>...</div>)
I keep getting undefined and I dont understand why...
I use "react-router-dom": "^4.3.1" according to my package.json
Please help!
You need to pass the router props into the component since you're using the render prop of the <Route/> component.
Also, In your App component you don't need BrowserRouter as Router since you're already wrapping <App/> in index.js. I changed the import and removed the wrapping <Router/> component.
import { Route, Switch } from 'react-router-dom';
class App extends React.Component {
...
render() {
if (this.state.auth) {
return (
<Switch>
...
<Route path="/editUser" render={props =>
<EditUser {...props} className="App" app={this}/>
}/>
</Switch>
);
}
}
}
I think you need to use the withRouter HOC on your EditUser Component in order to inject props like location.
See react-router getting this.props.location in child components
I am trying to wrap my routes so I can render something on every route, such as a header or any static content. I have looked at this post here:
Nested Routes in React Router v4
I tried wrapping my routes like they have there, but now the only thing that shows is the wrapping component, none of the children show.
So the only thing that shows is on the / and /dashboard routes:
Home Component
Dashboard
Here is the code:
Wrapping routes:
<Home>
<Switch>
<Route path="/dashboard" component={Layout} />
<Route component={NotFound} />
</Switch>
</Home>
Home component:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
class Home extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h2>Home component</h2>
<Link to="/dashboard">Dashboard</Link>
</div>
);
}
}
export default Home;
Layout component:
import React, { Component } from 'react';
class Layout extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h2>Layout Component</h2>
<h2>Layout Component</h2>
</div>
);
}
}
export default Layout;
Have you tried putting {this.props.children} in your Home component?
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
class Home extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h2>Home component</h2>
<Link to="/dashboard">Dashboard</Link>
{this.props.children}
</div>
);
}
}
export default Home;
Your layout needs a component, or instruction to know where to render the children.
Otherwise the router won't know where the children routes need to appear. The child component is passed to the layout as a property called children. You need to add this where you want it to appear:
{props.children}
Like:
import React, { Component } from 'react';
class Layout extends Component {
constructor(props) {
super(props);
}
static propTypes = {
children: PropTypes.node.isRequired,
}
render() {
return (
<div>
<h2>Layout Component</h2>
{props.children}
</div>
);
}
}
export default Layout;
I personally prefer using . react router config But if you use the bare router that should do it.
I am trying to implement a navigation example using react router and stuck in an error. Please find the code
app.js
-------
import React from 'react';
import ReactDOM from 'react-dom';
import Routes from './routes';
ReactDOM.render(Routes, document.getElementById('react-container'));
routes.js
---------
import { React,Component } from 'react';
import { DefaultRoute, Link, Route, RouteHandler,Router } from 'react-router';
import Page1 from './page1';
import Home from './home';
export default class Routes extends Component {
constructor() {
super();
}
render() {
return (
<Router >
<Route path="/" component={Home}>
<Route name="page1" path="/1" component={ Page1 }/>
</Route>
</Router>
);
}
}
home.js
-------
import React, { Component } from 'react';
export default class Home extends Component {
constructor() {
super();
}
render() {
return (
<div>
<Header />
{this.props.children}
</div>
);
}
}
page1.js
--------
import React, { Component } from 'react';
export default class Page1 extends Component {
constructor() {
super();
}
render() {
return (
<div>
<h1> Page 1 </h1>
</div>
);
}
}
I have babel transformer to convert from es6 to es5 and I get the following error on loading the app,
Uncaught Invariant Violation: ReactDOM.render(): Invalid component element. Instead of passing a component class, make sure to instantiate it by passing it to React.createElement.
Can anyone help me in troubleshooting this issue ?
The problem is in your routes.js. You are wrapping your routes inside of a component, then passing that to ReactDOM.render. You should be passing the jsx directly. My suggestions would be to unwrap routes from your class, and just export the jsx.
routes.js
---------
import React from 'react'
import { Router, Route } from 'react-router'
import Page1 from './page1'
import Home from './home'
let routes =
<Router>
<Route path="/" component={Home}>
<Route name="page1" path="/1" component={Page1}/>
</Route>
</Router>
export default routes
The error is complaining that you are passing a class, rather then calling React.createElement. Remember that this:
let someElement = <div>Hello</div>
Will turn into this:
var someElement = React.createElement(
"div",
null,
"Hello"
)