Routing for multi level `slug` url structure with React Router - reactjs

In my app, I have a hierarchy of categories. Each category has a slug defined in the category entity. What I am trying to achieve is hierarchical structure of the url as well to match the hierarchy of categories.
The resulting page is the landing page of last category in the url.
The app is written with React (with React router).
So, for example I have categories:
category-1
category-2
The url to category 2 should be:
/category-1/category-2
At this point I am digging for a solution and I can really find any best practices to achieve that.
The only thing that I found is recursive paths https://reacttraining.com/react-router/web/example/recursive-paths
This works from a routes perspective, but in this example, the component is actually rendered many times. How do I render it only for the last slug?
Or, am I even in the right direction here? What is the alternative?

Since routes are regular React components, they may be rendered anywhere in the app, including in child elements.
example may help you .

Related

How should I use React Router to swap out what I want to display in my header, body and footer?

From my understanding, React Router is good for when you want to reuse a container and different routes will change what's displayed inside of the container. However, I want it such that a route will change what's displayed in multiple containers.
For example, in my login page, I have my login form in the body container and my link to registration in the footer.
In my registration page, I have my registration form in the body and the link to login in the footer.
In my home page, I have a welcome message in the body and some buttons to change tabs in the footer.
What's the best practice for the component structure involved in this?
the best practice of React is making reused-components that help not to waste your time in coding, just only pick and reuse components in many different scenarios.
Base on your example, in login page and registration the footer may have the same design but only the links is different. We can create a layout named LinkInFooter and receive an array link objects to displayed:
// file /pages/login.js
<PageLayout>
<LoginComponent/>
< LinkInFooter links={[url: '/registration', label: 'registration page']}/>
</PageLayout>
// file /pages/registration.js
<PageLayout>
<RegistrationComponent/>
<LinkInFooter links={[url: '/login', label: 'login page']}/>
</PageLayout>
Below is a few tips for you:
Should have a WrappedLayout for all pages, I don't say it should be the same layout for all pages but it should have the same layout for many pages. That WrappedLayout will make your page look consistent when change route or hide / show chilren components.
Layouts/*.js : Layout directory is the place that hold all your custom small components that you want they are displayed same across your projects. For example: I customized a Select component that allow to search item, select multiple items... So that I create an custom <Select/> layout to replace html's <select/> on my project.
Components/*.js: this one hold all your components, either reusable or non-reusable. A component can be made by compose many others components: what can be reuseable should be created a new file for it and import to use. If not, create an internal component is enough.
Pay 5 minutes on UI design before start. Use the initial time to imagine the structure of pages then answer these questions :
How many component should I have for this pages?
Could be reused frequently?
Which items on the design should be layout?

React Router setup for 'unlimited' params

I am trying to implement the React Router in such a way that it supports a route like this:
/myPages/:pageName1/:pageName2/:pageName3/...
The idea is that, even though the page being rendered is only the last page, the pages are nested, and the depth is not something that is pre-determined. The component that renders the actual page needs to know the names of parent pages.
To clarify, the idea is that the page data in the backend are in a tree structure in such a way that, in the above example, page1 is the root page, page 2 is a child of page1, page 3 is a child of page2, etc. In addition, one page can have multiple children. The last child name (so pageName3 in the example) is what is being used to query the database and get all the content required to render the full page. The parent names are required to render navigation-related subcomponent. I should also mention that just having /myPages/:pageName3 and getting all parent names from the backend is not really an option. I could fetch that information from the backend, but the URL presented to the user still needs to have that structure.
I am hoping that there's a way to get this type of information as an array, but I am having a hard time finding an example like this on the web.
maybe this can help.
https://github.com/ReactTraining/react-router/blob/d28d46dce08a5756a085f7e5eebb5169ea59e40b/packages/react-router/docs/api/Redirect.md#from-string
states:
A pathname to redirect from. Any valid URL path that path-to-regexp#^1.7.0 understands.
maybe you can combine
<Redirect from='/users/:id' to='/users/profile/:id'/>
with
var re = pathToRegexp('/:foo+', keys)
(taken from https://github.com/pillarjs/path-to-regexp/tree/v1.7.0#one-or-more)
then you'll end up with
<Redirect from='/:pageName+/:id' to='/:id'/>

different nav bar for different pages in react

For my application, I have a nav bar which has different functionality for different pages. ie. 1 page has a map and the search will search for addresses and another page has a list and the search bar will filter the list. There are also different buttons on each page too.
What's the best way to implement something like this in react? I've thought about creating a different search bar component for every page and just rendering a different one for each route but I don't have enough experience in React to go ahead with that decision. Is there a more efficient alternative?
Create a new Navbar component named something like NavBarController. While calling the navbar controller component pass in the "Type" as prop. Type should be a state and should change depending on the page the user is on.
<NavBarController type={1}></NavBarController>
You would just create a few different NavBars and then NavBarController will handle whichever navbar you want to display out of your multiple navbars.
Your NavBarController will return something like this:
return (props.type===1?<NavBarHome/>
:props.type===2?<NavBarMap/>
:props.type===3?<NavBarList/>)

Possible to limit list of params when using React Router?

Using React with React-Router in a project and am wondering if it's possible to limit the possibilities for param names, like so:
www.mydomain.com/books/:id
and allowing 'Catcher in the Rye' and 'To Kill A Mockingbird' to be passed through, like so:
www.mydomain.com/books/catcher-in-the-rye
www.mydomain.com/books/to-kill-a-mocking-bird
I want to say that only a specific set of books can be used in place of :id (just so someone can't type in www.mydomain.com/books/whatever-they-want and have an empty React component render).
I do currently have a '*' route that catches anything not mentioned, but because params are dynamically generated based on whatever is passed, that won't help in this case.
Is this possible? Thanks.
You need to handle this logic in the component. Depending on if this is an already mounted component or not you will need to put the logic in the appropriate function (componentDidMount, componentWillReceiveProps)
if(!(this.props.params.id in myAcceptableParameters)){
redirect to a 404 here
}

AngularJS different child components vs child routes

Newbie using AngularJS 1.5 with ES6, a component-based design and the new Component Router.
Let's consider a simple Survey application. Any given Survey has an instructions page and a list of Questions.
When the end user accesses a given Survey, he must be shown the instructions page. He must then navigate through the different Questions, which may span several pages. Upon reaching the last Question page, he must be shown a summary page with all his answers.
Ideally, I would like to have the following route mappings:
/surveys/:id : alias to /surveys/:id/instructions
/surveys/:id/instructions : displays the survey instructions
/surveys/:id/entry : displays the survey for entry by the end user
/surveys/:id/summary : display a summary of all survey answers entered by the end user
Ideally, the SurveyComponent (mapped to /surveys/:id) would load the Survey on route activation ($onRouterActivate method) and expose the retrieved Survey to its child components through its <ng-outlet/> template tag. The child components, mapped to the correct sub-routes, would then bind to this Survey and render the appropriate display.
I have been unable to achieve this, as it seems that <ng-outlet/> cannot be used to send data to child components.
Is my approach correct and am I missing something? Or is the route/sub-route mechanism inappropriate for this?

Resources