react router 6 custom path match test - reactjs

I'm writing React app inside a non-React app, and I have no control over the relative route of my app (for example could be foo.com/bar/my-react-app). So the requirement is matching routes against the end of the URL(this is safe because the React js files are being loaded only when the user navigates to the route of my react app, so no collisions).
based on my check, the path check of Route in router-router v6 is not flexible or configurable, but in my case i need a custom check, with the end of the string's route.
for example one of the next checks would do the trick:
prefix is not possible
<Route path="*/admin" element={<UserApp />} />
custom function is not possible either
<Route path={(route)=>route.endsWith("admin")} element={<UserApp />} />
I started looking at the source code and they using primarily <string>.startsWith and do not expose many customization options, so I came here to you experts before wasting a few hours trying to recreate the path match behavior with the low level components.
by the way BrowserRouter basename attribute does not help me either because i have no guarantee of the URL+route my app would be installed, so the check must rely on the end of the location string.
so, there is an easy way to make a route with custom path validation?

For anyone who encountered in my case - v6 is much less flexible as it does not support path-to-regexp path matches nor custom render method for Route... so Route path="*/admin" would just work out of the box in v5
they should have left it in the API in my opinion. migrating back to v5 was trivial for my case and solved the issue.

Related

Share Info betwen brothers components

I have to find a solution to share information between components in React js.
The use case is that in an online store when a guest tries to add a product to his wishlist he should be redirected to the registration page and after registering it should be automatically added to his wishlist.
I tried with window.localStorage and made it work but I was told that it was not necessary to do it this way, the page is a bit complicated and the components do not have common ancestors the component tree is like this.
<App>
<Routes>
<SearchPage>
<Gallery>
<GalleryItem>
<AddToListButton>
</AddToListButton>
</GalleryItem>
</Gallery>
</SearchPage>
</Routes>
</App>
<App>
<Routes>
<Signin>
</Signin>
</Routes>
</App>
<App>
<Routes>
<Route>
<WishlistPage>
<Wishlist>
</Wishlist>
</WishlistPage>
</Route>
</Routes>
</App>
and I have to pass the button information to the registration page and then make it redirect to its wish list when it registers, apart from useContext what other method could I use?
It depend on the requirements, using localStorage allows you to store user session between tabs, even between sessions.
sessionStorage works similar but it stores data only within single session (for example - one browser tab).
You can try to use React Context API (as you mentioned).
One more is to use centralized store (for example React Redux).
Of course there are some additional browser features like IndexedDb or websql to persist some data for the user, but their support for various browsers can be different.
You have plenty of options, starting with the ones you have out of the box.
Lift the state up The best solution for non complex use cases is to get the state to the parent component and pass down the state value and a function that modifies the state to this sibling components that you want talking to each other.
Context If you have a piece of state that lots of children components are depending on you can create a context, wrap the parent component in a context provider and consume that in the childrens with useContext.
Or you can find libraries for state management here
If this "add to wishlist" action is something that happens in the server I highly recommend react-query. If not, try zustand it's easier to use than redux and feels very similar to context but with less boilerplate and without the need to wrap things in a context provider

Build Next.js multi-language application with client-side routing

I'm currently working in a multi-language application with Next.js that I intend to host in an S3 bucket.
In this site, I need to maintain an application state across routes, by doing client-side routing from one route to another.
Since I need to support 40+ languages and internationalization, the process to do so is the following:
In next.config.js, use exportPathMap to generate /[language] routes with a variable inside "query" that contains that particular locale for the language.
Load this locale in getInitialProps of _app and pass it down with a Provider, to be consumed in any part of the application using the context API.
To support client-side routing, I've wrapped the next/link component in a custom Link that passes down all props and sets the "as" prop to "/[language]/[route]".
This solution works for now, but ideally, I wouldn't need to "mock" the routing with the "as" prop. I have found that dynamic routing in next does not allow client-side routing in a way to avoid refreshing the page to a new .html file that matches the dynamic path.
E.g:
Using the following directory structure:
/pages
index.tsx
/[lang]/
home.tsx
dashboard.tsx
From index.tsx, clicking on a link from next/link that redirects to /en/dashboard will trigger a request to the server and refresh the page completely. Thus, losing the client state.
Is there a better solution for this? It seems like a very common problem to solve, yet I cannot find an elegant solution using Next.js.

How to render a page to base url in react

I need to render a page for base url in react. I defined base url as,
<Router basename="/baseUrl">
<Switch>
<Route path={"/childUrl"}
</Switch>
</Router>
I am able to render page via /baseUrl/childUrl. When accessing, /baseUrl it redirects to /baseUrl/childUrl. How can I set a different page to /baseUrl
I know this is old, but in case anyone else stumbles upon this I would recommend using redux-first-router. It lets you dispatch actions either by changing the url in your browser, or the regular react way. This lets you control how components are rendered and keep the state of your application in sync with the url, without having multiple sources of truth.
Michael Sargent did a brilliant explanation, which can be found here.
And of course, you can also check out the git repo.

What is the different between Router vs Route in react-router-dom

In the React-Router documentation I have seen that It has import both Route and Router modules from react-router-dom. I would like to know what is the different between those two modules?
Router
Router component is what makes the connection between browser location and the react application. It doesn't render anything visible on your page. It just exposes API to interact with location changes of the browser via React context. So any component down the tree can use this API to change their behavior based on location changes in the browser or change the browser location into what they want.
Router is the abstract for all other specific router components. Practically, we use a specific implementation of it like BrowserRouter, MemoryRouter, and HashRouter which use different methods to manage browser history. Also, Router is usually a top-level component in the component tree and use only one time in the entire application. All other react-router components should be descendants of Router as they can't function without the API which Router provides.
Route
Route is much simple to explain. It just renders some UI when a location matches the route’s path. So an application can have many Routes based on its layout complexity in different levels of the component tree. Also, Route has some additional props to configure how the match should happen. Route internally use API provided by Router to access the location and decide whether to render the given component or not.

What is routing? Why is "routing" needed in single page web apps?

I understood that routing libraries for SPAs like https://github.com/ReactTraining/react-router help to parse the URL and put the app into a corresponding state of a state machine.
Is there more to routing than this?
Why is routing needed in the first place?
Why are URLs important? For example in a desktop app there are no URLs, so what's the big deal about them in a web app?
I also have this problem: "Why do we need routing?". You can write apps without routing at all. The code can get messy but still, it is not impossible.
My biggest reason for having routing is because if the user hits the Back button of the browser (Forward button as well, for that matter), he will not be navigating within the app. The user might expect to navigate within the app using the history of the different "pages" he loaded previously. Instead, he will be thrown out of the web app. Hitting the Refresh button would also throw him to the root of the app.
From the user's point of view, it is a regular web app (he doesn't need to know how it is designed: SPA or otherwise) and it should work as any web app/website should work. Routing ensures this, doesn't it?
This is a very good question, and one that I don't see discussed as often as I think it should be. The short answer is that often, in a Single Page Web Application, you don't need routing. If you are building an application which doesn't require its pages to be indexed by Google, and you either don't care, or don't want the user to be able to Bookmark pages, then there is no reason to implement routing.
In an SPA, routing adds additional complexity and effort, so if you can avoid doing it, you should. Of course, modern frameworks such as Angular and React provide facilities for making routing much easier, but even then some things can be hard to do with routing, for example animating between pages.
A good example of a web application where routing would be redundant would be a multi-page form which you want to control the user's passage through and possibly prevent them from returning to pages which have became inapplicable.
Implementing such a form with routes would be a nightmare as you would have to prevent the user from visiting certain pages in their history.
It's useful to ask yourself what a route actually is in a SPA. It's easy to think of it as just a 'web-page', but what it really is is a state, and when you navigate between routes what you are really doing is navigating between different states of the app. The fact that the appearance of the app may change between states is incidental to what is really going on. So what a route does is give the user a means of returning to particular states of the app.
You should only implement a route in an SPA when there is a state of the app which you want the user to be able to return to.
An alternative, and perhaps more useful way of doing this, would be to implement Undo and Redo mechanisms.
Of course, even when you don't have routes you still have to care about what happens when the user clicks the History Back button, but then you simply have a modal alert which warns them that they are about to leave the app should they proceed with the navigation.
In desktop applications you have buttons and other controls to get what you want. So routing in UI apps would be the set of all UI controls.
In web apps on the other hand, all functionality is accessed via some text which is the links and the parameters.
A URL is the path to access a functionality. Routing is like the mechanism to decide which functionality to call based on the provided URL and params.
So basically routing is a mapping between an URL and the functionality of a web server.
Routing in SPAs is used to load certain parts of the web app e.g. yourappurl.com/profile/userid/ will load the profile part of an SPA with the right user profile corresponding to the userid. This can be seen in the GitHub example you provided:
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="about" component={About}/>
<Route path="users" component={Users}>
<Route path="/user/:userId" component={User}/>
</Route>
<Route path="*" component={NoMatch}/>
</Route>
SPA refers to the fact that in general you have an index.html as your "main view" and then depending on the routing you add/remove certain parts from the index.html with frameworks like React or AngularJS etc.
I have the same question from time to time.
I would like to say router in SPA is a component hierarchy helper.
As #tech4242 pointed out, we don't have an something like segue in iOS. So what should we use to help users navigate if we don't use router? We are talking about SPA here. So we can manage this in store or state. Yes, that's feasible but not preferable.
Try to think this from the perspective of using a component-oriented library (either React or Vue). Using router help us use a certain component for a specific route. When users move back and forth between different route, we are relying on the route to tell what component to display. We simply couple a component with a specific route, which makes our root component (normally called App) clear, maintainable and readable. Without router, either the root component or state would be messy and hard to maintain.

Resources