I'm using React Router to create a multi page app. My main component is <App/>
and it renders all of the routing to to child components. I'm trying to pass props via the route, and based on some research I did, the most common way for child components to tap into props passed down is via the this.props.route
object that they inherit. However, this object is undefined for me. On my render()
function in the child component, I console.log(this.props)
and am return an object that looks like this
{match: Object, location: Object, history: Object, staticContext: undefined}
Doesn't look like the props I expected at all. Here is my code in detail.
Parent Component (I'm trying to pass the word "hi" down as a prop called "test" in all of my child components):
import { BrowserRouter as Router, HashRouter, Route, Switch } from 'react-router-dom';
import Link from 'react-router';
import React from 'react';
import Home from './Home.jsx';
import Nav from './Nav.jsx';
import Progress from './Progress.jsx';
import Test from './Test.jsx';
export default class App extends React.Component {
constructor() {
super();
this._fetchPuzzle = this._fetchPuzzle.bind(this);
}
render() {
return (
<Router>
<div>
<Nav />
<Switch>
<Route path="/" exact test="hi" component={Home} />
<Route path="/progress" test="hi" component={Progress} />
<Route path="/test" test="hi" component={Test} />
<Route render={() => <p>Page not found!</p>} />
</Switch>
</div>
</Router>
);
}
}
Child:
import React from 'react';
const CodeMirror = require('react-codemirror');
import { Link } from 'react-router-dom';
require('codemirror/mode/javascript/javascript')
require('codemirror/mode/xml/xml');
require('codemirror/mode/markdown/markdown');
export default class Home extends React.Component {
constructor(props) {
super(props);
console.log(props)
}
render() {
const options = {
lineNumbers: true,
theme: 'abcdef'
// mode: this.state.mode
};
console.log(this.props)
return (
<div>
<h1>First page bro</h1>
<CodeMirror value='code lol' onChange={()=>'do something'} options={options} />
</div>);
}
}
I'm pretty new to React so my apologies if I'm missing something obvious. Thanks!
To recap, if you need to pass data from Link through to the new component that's being rendered, pass Link s a state prop with the data you want to pass through. Then, to access the Link s state property from the component that's being rendered, use the useLocation Hook to get access to location.
To pass props, add them to the JSX, just like you would with HTML attributes. To read props, use the function Avatar({ person, size }) destructuring syntax. You can specify a default value like size = 100 , which is used for missing and undefined props.
If you need to access the v6 versions of these objects you will use the React hooks, useNavigate for a navigate function which replaced the history object, useParams for params instead of match. params , and useLocation for location .
You can pass props to the component by making use of the render
prop to the Route
and thus inlining your component definition. According to the DOCS:
This allows for convenient inline rendering and wrapping without the undesired remounting explained above.Instead of having a new React element created for you using the
component
prop, you can pass in a function to be called when thelocation
matches. The render prop receives all the same route props as the component render prop
So you can pass the prop to component like
<Route path="/" exact render={(props) => (<Home test="hi" {...props}/>)} />
and then you can access it like
this.props.test
in your Home
component
P.S. Also make sure that you are passing
{...props}
so that the default router props likelocation, history, match etc
are also getting passed on to theHome
component otherwise the only prop that is getting passed down to it istest
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With