Creating react pages with unique urls - reactjs

I have a route with a url that changes based on the id of the object I clicked to access the route.
//Route
<Route path="InColl/:id" component={InColl}/>
//InColl Component
import React from 'react'
import './css/InColl.css';
export default function InColl({match}) {
const userId = match.params.id;
return (
<div className="margin">
<div className="inv">
Hello World!!!
</div>
</div>
)
}
The :id changes via the link component underneath. I mapped an array of objects each with their own unique id. Depending on which object I click, I will be taken to a new page with the url looking like "
http://localhost:3000/InColl/(The Id of The Object)".
<Link to={"InColl/" + this.props.c._id} >
For some reason the InColl page with the unique id doesn't render anything. I'm not sure what the issue is and I would appreciate some help. Thank you.

/The routes need to be a relative path
change route to
<Route path="/InColl/:id" component={InColl}/>
and link to
<Link to={"/InColl/" + this.props.c._id} >

Related

React-js undefined props dynamic page when accessing URL directly

I'm trying to create a webshop with React as front-end framework and have gotten stuck on the routing of the products. I currently have all the products in a json table and import these into my webshop which works fine when the product page is accessed through the link but whenever I go to the product page directly I get an error stating that my props are undefined. I have
<Router>
<Switch>
<Route exact path="/products/:productId" component={Product} />
</Switch>
</Router>
as my router to the product page and link to the page using:
<Link to ={{pathname:`/products/` + product.url, ProductdetailProps:{title: product.title, description: product.text, image: product.image}}}>
The Product page looks like this:
export const Product = ({location}) => {
return (
<div>
<img src={location.state.image} alt={backupImage}/>
<p>{location.state.title}</p>
<p>{location.state.description}</p>
</div>
);
};
Should I keep on "creating" the product pages this way and if so can someone help me with this or should make each product page seperately and link those?

React router - Navigate inner pages with sub route

I am using react routing for navigation among pages. This navigation having child link,
Parent Link 1
Parent Link 2
a. parent1/child link 1
b. parent1/child link 2
a. parent2/child link 1
b. parent2/child link 2
c. parent2/child link 3
How to implement this navigation in react-router.
Please see the attached image with this post to get clear understanding on my query.
class App extends Component {
render() {
return (
<Router>
<div style={{width: 1000, margin: '0 auto'}}>
<ul>
<li><Link to='/'>Home</Link></li>
<li><Link to='/topics'>Topics</Link></li>
</ul>
<hr />
<Route exact path='/' component={Home} />
<Route path='/topics' component={Topics} />
</div>
</Router>
)
}
}
At this point, ” takes in a path and a component. When your app’s current location matches the path, the component will be rendered. When it doesn’t, Route will render null.”
function Topics () {
return (
<div>
<h1>Topics</h1>
<ul>
{topics.map(({ name, id }) => (
<li key={id}>
<Link to={`/topics/${id}`}>{name}</Link>
</li>
))}
</ul>
<hr />
<Route path={`/topics/:topicId`} component={Topic}/>
</div>
)
}
when we go to /topics, the Topic component is rendered. Topics then renders a navbar and a new Route which will match for any of the Links in the navbar we just rendered (since the Links are linking to /topics/${id} and the Route is matching for /topics/:topicId). This means that if we click on any of the Links in the Topics component.
It’s important to note that just because we matched another Route component, that doesn’t mean the previous Routes that matched aren’t still rendered. This is what confuses a lot of people. Remember, think of Route as rendering another component or null. The same way you think of nesting normal components in React can apply directly to nesting Routes.
At this point we’re progressing along nicely. What if, for some reason, another member of your team who wasn’t familiar with React Router decided to change /topics to /concepts? They’d probably head over to the main App component and change the Route
// <Route path='/topics' component={Topics} />
<Route path='/concepts' component={Topics} />
The problem is, this totally breaks the app. Inside of the Topics component we’re assuming that the path begins with /topics but now it’s been changed to /concepts. What we need is a way for the Topics component to receive whatever the initial path as a prop. That way, regardless of if someone changes the parent Route, it’ll always just work. Good news for us is React Router does exactly this. Each time a component is rendered with React Router, that component is passed three props - location, match, and history. The one we care about is match. match is going to contain information about how the Route was matches (exactly what we need). Specifically, it has two properties we need, path and url. These are very similar, this is how the docs describe them -
path - The path pattern used to match. Useful for building nested Routes
url - The matched portion of the URL. Useful for building nested Links
Assume we were using an app that had nested route’s and the current URL was /topics/react-router/url-parameters.
If we were to log match.path and match.url in the most nested component, here’s what we would get.
render() {
const { match } = this.props // coming from React Router.
console.log(match.path) // /topics/:topicId/:subId
console.log(match.url) // /topics/react-router/url-parameters
return ...
}
Notice that path is including the URL parameters and url is just the full URL. This is why one is used for Links and the other used for Routes.
When you’re creating a nested link, you don’t want to use URL paramters. You want the user to literally go to /topics/react-router/url-parameters. That’s why match.url is better for nested Links. However, when you’re matching certain patters with Route, you want to include the URL parameters - that’s why match.path is used for nested Routes.

React router v4 replace param with <Link/>

My DashBoard component renders a shared component called PostComments that renders a list wrapped with <Link/>, When a list is click the page navigates to Profile component and on this component i also have the PostCOmments
Now, if i click one of the list on my Profile component the url param just stacks up Like this, http://localhost:8080/#/dashboard/5b6c5223514959110c492086/49182d98319138e31da42356
<Link replace to={`${match.url}/${i.comment_from._id}`}>
<div className="comment-user-image" style={{backgroundImage: `url(${i.comment_from.photo_url})`}}>
</div>
</Link>
You'll need to manually replace the last part of your url because you re-use it.
const splitUrl = match.url.split('/'); // Split into array
splitUrl.splice(-1, 1, i.comment_from_id); // Replace the last part with the new id
return (
<Link replace to={splitUrl.join('/')}> // Recreate the correct url
// ...

react router redux url

I am making my first web-app using react, react router v4, and redux/react-router-redux.
it is a shopping site. I have my list of my products saved in the store and can access them fine. I have produced a products list page, when clicking on the products' image i have routing setup to take me to a new url(/'productmodel').
Currently I have a 'ProductPage' component for which I have passed in props relevant to the specific product, for each corresponding route, within my router. This seems like a very long way of doing things.
What I would like to do is render for each of the routes and then have the ProductPage component itself, render the right product depending on the route (URL address).
What is the best way to do this??
Thank you in advance :)
Are you after something like this?
ProductsListPage:
....
render() {
<div>
{this.props.products.map(product =>
<Link key={product.id} to={"/product/"+product.id}>
{product.name}
</Link>
)}
</div>
}
....
ProductPage:
....
componentWillMount() {
this.props.actions.getProduct(this.props.match.params.productid);
}
....
render() {
<div>
<span>{this.props.product.name}</Link>
</div>
}
....
Your route for product page would look like this:
<Route exact path="product/:productid" component={ProductPage} />
So what's happening here is when you click on a product on Products List page, you get redirected to the product page that has the product id as a parameter. On component mount on product page, you retrieve the product passing the productid from params (url).
ok so I manage to do it!
I created a ProductPageContainer inorder to pass my products list from the store:
function mapStateToProps(state) {
let products = state.kitsProducts;
return {
products: products
};
};
I then, within my component, got the productid from the params; as suggested by Hossein:
createProductPageComponent() {
let activeProduct = this.props.products.filter(product => product.id === this.props.match.params.productid)
return activeProduct.map(product =>{
return (
<ProductPage
key={product.id}
brand={product.brand}
productName={product.model.toUpperCase()}
price={"£"+product.price}
productImage={product.image}
text={product.text}
/>
)
})
}
and now my product page renders to the the right route, depending on which product was selected in the previous product list page. And the right product, depending on what route it has been rendered in.
Thanks Hossein!!! You helped me more than you may think!

switching between certain component on a page using nested route in react router

I am trying to create a job site. Following pages shows list of all the jobs which is shown once user hits search button from home page. So basically this is the second page.
In this page i am catching all the search parameter from url and fetching data from api and result is shown as below:
Once the user clicks individual joblist, detail page should load on the same page without changing header and fixed component with unique URL for the detail page. Expected result shown below:
My Problem:
I manage to create a nested Route, which renders detail page on the same page and also has a unique url. But it renders on top of existing job list. I mean if user clicks on joblist1, detail page renders on top of subsiquent list(above list: 2, 3, 4). But expected result is to only render detail page but not list of jobs when individual job list is clicked.
My code: I have only shown part of the code for brevity and simplicity.
1) jobs.js: Passes state data to child component to show list.
return(
<div>
<div>
fixed component
</div>
<div>
<RouteHandler />
<JobLists joblists={this.state.joblists} />
</div>
</div>
)
2) jobList.js: uses .map function to go through all data and handleclick function generate url and opens that url once user clicks individual link. Router catches nested route and loads value inside jobs.js in " ".
handleClick: function(i){
var base_path = window.location.protocol + '//' + window.location.host;
base_path += '/#/jobs-detail';
window.location= base_path;
},
render: function(){
var jobListRow = this.props.joblists.map(function(jobrowobj, i){
return(
<div key={jobrowobj.id} onClick={this.handleClick.bind(this, i)}>
<img src={jobrowobj.logo} alt="" />
<h3>{jobrowobj.title}</h3>
</div>
)
}.bind(this));
return(
<ul id="joblists">
{jobListRow}
</ul>
)
}
3) Route file:
var routes = (
<Route handler={App}>
<DefaultRoute handler={Home} />
<Route name="jobs" path="jobs" handler={Jobs}>
<Route name="jobs-detail" handler={JobDetail} />
</Route>
<NotFoundRoute handler={NotFoundPage} />
</Route>
);
I am not sure what is the best way to switch certain section (component) on a page as in my case switching between joblist component and jobdetail component. As you can see i am only able to load other component on top of existing component which is not the expected result.
Also would appreciate if any hint is given to maintain scroll position on the job list on user hitting back button.
I suggest you to upgrade your react-router to 1.0.0-rc1, and the API is more clear. Your problem is similar to the official introduction. The nested component will be passed as this.props.children, and you can insert it into the jobListRow.
About the scroll position, there's a github issue discussing how to restore it :)

Resources