I want to get the id from the URL therefore I can use this id to get and output the user info but I can't get id from URL. I've seen useParams() but I think it is not applicable with class component. May I know if there is an alternative solution for this?
async componentDidMount(){
const stud_id = this.props.match.params.id;
console.log(stud_id);
}
see error message from console here
The most common way of reading URL params in React is using React Router. In React Router, you get URL params with this.props.match.params like you are trying to, but you have to call your component inside a Route, like for example:
<Route
path="/:id"
component={YourComponent}
/>
instead of just
<YourComponent />
So that your component receives the match prop and can access this.props.match.params.id
If you're using
<Route path="/blah" component={()=><YourComponent someProp={someProp}>}/>
I mean, with arrow function as it child component, you have to pass the pros of the father (Route) to the child (YourComponent) like that:
<Route path="/blah" component={({match})=><YourComponent match={match} someProp={someProp}>}/>
Because you're creating a new "generation" so you have to pass the props by your self
Related
Well, I try to understand legacy code with React routes onboard.
I have an url like
/home/reports/some_report_numbers
when user changes the ulr like that:
/home/reports/some_report_numb
I want to check if "some_report_numb" exists in props, in this.props.location.pathname. If exists - fine, go that way, otherwise go another way.
Maybe it is a wrong approach at all? Well, when the report is shown and user just deletes some letters in url I need to redirect to /home/ page. To do that I need somehow to check if that report with that numbers exists at all.
Maybe it could be done via
<Route name={SomeRouteName} path='reports/:reportId' component={HomePage} />
According to the documentation of react-router-dom
Link: https://reacttraining.com/react-router/web/example/url-params
match become an object that can be used in your component. Like explain in the documentation, you have access to match object with the following steps:
Route component as this.props.match
Route render as ({ match }) => ()
Route children as ({ match }) => ()
withRouter as this.props.match
matchPath as the return value
For example, if you have the following route:
<Route path="/reports/:reportId" component={HomePage} />
In your component, you can access to this with: this.props.match because it's an object and inside it, you will have what you want.
After that, you could check what params you have in your URL.
Now, if you want to redirect the user, you can use <Redirect to={'/your/path'} />
Here's what I have done so far,
This is the Route that I have defined for a page
<Route path='emails/user/view/:id' component={AccountEmails} />
And here's where the Component is being rendered
const AccountEmails = ({params: {id}}) => <ReceiptsListBox url={"/api/accounts/"+id+"/receipts.json"}></ReceiptsListBox>
Now, within the render() method of the component, I tried to console.log(this.props.location.query) unfortunately this.props.location is undefined.
Here's the YouTube video that I have referred to.
react-router version 2.8.1 and react version 15.3.2
Use this:
const AccountEmails = props => {
const {id} = props.params;
return <ReceiptsListBox
url={"/api/accounts/"+id+"/receipts.json"}
{...props} // =====> notice this part, important
</ReceiptsListBox>
}
Reason is: You are passing only url in props, not all the props values that AccountEmails receives from Routes, because of that location is not available inside ReceiptsListBox component.
Solution is pass all the props that AccountEmails component receive along with one extra url value, by that way location will be available inside ReceiptsListBox component.
I'm getting the list of products in ProductList, in which, I need to pass the selected product object to Product.
Currently, I'm trying pass the id as a route param and get the product object again. But I want to send the entire product object from ProductList to Product.
My Route is
<Route path={joinPath(["/product", ":id?"])} component={Product} />
ProductList component Link
<Link to={"/product/" + this.props.product.Id} >{this.props.product.Name} </Link>
How to pass product object to Product as a prop?
the below one throws error in Typescript saying the following property does not exist on Link Type.
<Link to={"/product/" + this.props.product.Id} params={product}>{Name}</Link>
I tried the following questions, but none seems to have my issues.
Pass props in Link react-router
<--- this is similar to my issue, but answer doesn't work for react-router v4
react-router - pass props to handler component
React: passing in properties
The "to" property of Link can accept an object so you can pass your props like this :
<Link to={
{
pathname: "/product/" + this.props.product.Id,
myCustomProps: product
}
}>
{Name}
</Link>
Then you should be able to access them in this.props.location.myCustomProps
I would suggest using redux for retrieving the data. When you navigate to product route you can get the product details by dispatching some action.
componentDidMount() {
let productId = this.props.match.params.Id;
this.props.actions.getProduct(productId);
}
The product route should be connected with the the store.
Hope this helps.
You can try to do it through query params as in Pass object through Link in react router, which is quite ugly.
Also you can try to replace Link with some other element, e.g. button and in click listener do location change via browserHistory.push({ pathname:"/product/" + this.props.product.Id, state: this.props.product}) and and product as state property.
Say I have http://www.example.com/page/#/search routed like this:
<Router history={hashHistory}>
<Route path='/search/' component={SearchPage} />
</Router>
And when the user does a search on the page using the provided name and age search boxes (either can be left out, or both can be filled), I want it to redirect to:
http://www.example.com/page/#/search/?name=whatever%20name&age=15
Which will display the results for this particular search. This would also allow linking directly to search results.
Now inside my SearchPage component, how can I check if ?name= or ?age= or any other search parameters have been provided?
In your container say SearchPage you can access queryParams like this
this.props.location.query.yourKey.
As an example
class SearchPage extends React.Component{
componentWillMount(){
const {name, age} = this.props.location.query;
//here you can give default values if they are empty
//do whatever you want
}
}
There are two ways of achieving this either you can use params or query values.
By params:
In the route first define your optional parameters like this:
<Router history={hashHistory}>
<Route path='/search(/:name)(/:age)' component={SearchPage} />
</Router>
Include componentWillReceiveProps() method in your component it will get triggered whenever component receive any new props, like this:
componentWillReceiveProps(newProps){
console.log(newProps.params.name, newProps.params.age);
// here you can check the props value
}
In the component you can check the value by this.props.params.name or age.
By query parameter:
no change is required in the route, just pass the values in url and check like this:
this.props.location.name or age.
Read this article for about params and query values in react: https://www.themarketingtechnologist.co/react-router-an-introduction/
With the latest update "location.query" is not exposed, we have to use "location.search" to get the optional unnamed parameters. However, The named optional parameter still can be read through "props.match.params"
Route :
<Route path="/partner/list-space/step-1/:_id?" component={ListSpace}/>
Fetching the named optional parameter "id" in component or hooks
let id = props.match.params._id;
To fetch the unnamed optional parameter such as "space" from the url.
http://localhost:3000/partner/list-space/step-1/123?space=new&guests=4
We have to use "querystringify".
import qs from "querystringify";
const qsParams = qs.parse(props.location.search);
Results :
props.match.params._id => "123"
qsParams.space => new
qsParams.guests => 4
Precursor:
I am refactoring two components, Photos.js and PhotoDetailsModal.js. Originally they had a relationship like this:
<Photos>
<PhotoDetailsModal/>
</Photos>
my route '/photos' looked like the following, and Photos.js simply controlled the the rendering of PhotoDetailsModal internally through state and a little bit of data-gathering:
<Route path="photos" component={Photos}/>
If I want to decouple these two components and make a route like this:
<Route path="photos" component={Photos}>
<Route path=":photoId" component={PhotoDetailsModal}>
</Route>
</Route>
How do I pass props into the PhotoDetailsModal component? Prior to this re-design, Photos.js simply handled all the data gathering and just passed expanded photo data to <PhotoDetailsModal/> internally through some props.
I do know that inside Photos.js I will eventually use {this.props.children} to render PhotoDetailsModal, I just want to know how to do all of my data-passing from <Photos/> to <PhotoDetailsModal/> using this new routing.
With v2/3 of React Router, you will have to use cloneElement to re-render the this.props.children element with the desired props. Basically, your code will look like this:
render() {
const { children } = this.props
return (
<div>
{ children && React.cloneElement(children, { other: 'foo' }) }
</div>
)
}
The documentation for React Router includes this passing props to children example app which does the same thing.