Question mark inside react router path - javascript

I'm trying to pass parameter inside my URL, but I have a problem with reading. I'm using react-router v4.
URL: http://localhost:3000/reset?token=123
I'm trying to read it this way:
<Route
path="/reset?token=:token"
component={Reset}/>
But this prints empty object console.log(this.props.match.params);. What is strange I have tried to change question mark to other character and looks like it solves my problem, but I would like to keep question mark anyway.
URL: http://localhost:3000/reset_token=123
<Route
path="/reset_token=:token"
component={Reset}/>
This already works console.log(this.props.match.params);. Any idea how to make question mark works also correct? Really important to me is to keep using just react-router without any external libs.
Cheers,
Daniel

How did I solved this issue.
http://localhost:3000?token=mypetismissing
export default function ({ location }) {
const urlParams = new URLSearchParams(location.search);
const token = urlParams.get('token');
console.log(myParams)
return (
<div>
{token}
</div>
)
}

You need query-string
Example:
http://yoursite.com/page?search=hello
const queryString = require('query-string')
class ProductsPage extends React.Component {
componentDidMount() {
let search = queryString.parse(this.props.location.search).search
console.log(search) // ==> hello
}
...
}

Change your path to '/reset'. That'll get the page to render with the token still in the url and you'll be able to grab that token. Happy coding :)
<Route
path="/reset"
component={Reset}/>

Extracting Query Parameters from react router path
URL: http://localhost:3000/reset?token=123
First import useLocation from 'react-router-dom
And do this inside your functional component
const { search } = useLocation();
const parameters = new URLSearchParams(search);
const token = parameters.get('token');

Related

react-router v6 history.location.search replacement

In react-router v5 I was able to use
let keyword = history.location.search
but in react-router v6 I get an error so what is the replacement for that code?
Edit: BTW I am not so good at router and currently converting a code from v5. I was wondering what should keyword return in v5? The path I am currently in?
It's was always the case that you should have accessed the search value from the location object instead of the history object.
See history is mutable
The history object is mutable. Therefore it is recommended to access
the location from the render props of <Route>, not from
history.location. This ensures your assumptions about React are
correct in lifecycle hooks.
If the tutorial is showing using history.location.search I wouldn't give it much weight.
In react-router-dom#6 however, there are no longer any route props, i.e. no history, location, or match props. You instead access these all via React hooks. Note that the history object is also no longer directly exposed out to components, replaced by a navigate function via the useNavigate hook.
To access the queryString RRDv6 introduced a new useSearchParams hook.
Given URL "/somepath?someQueryParam=123"
import { useSearchParams } from 'react-router-dom';
...
const [searchParams, setSearchParams] = useSearchParams();
const someQueryParam = searchParams.get("someQueryParam"); // 123
Additional Question
Edit: Btw I am not so good at router and currently converting a code
from v5 I was wondering what should keyword return in v5 ? The path I
am currently in?
location.search is a string, so you could process the string manually, or create a URLSearchParams object.
Check the RRDv5 Query Parameters demo
They create a custom useQueryHook:
function useQuery() {
const { search } = useLocation();
return React.useMemo(() => new URLSearchParams(search), [search]);
}
then access named query params with the getter:
let query = useQuery();
...
const name = query.get("name");
example url: https://example.com/?foo=bar
import { useSearchParams } from 'react-router-dom'
const Component = () => {
const [searchParams, setSearchParams] = useSearchParams()
const foo = searchParams.get('foo')
console.log(foo) // "bar"
return <></>
}
Obviously, you need to use this inside a router.
Note: all search param values are strings.

Impossible to get part of URL with react router?

How can I always get the same part of the URL in react?
example:
http://localhost:3000/supplier/924511e8-9056-4c1e-9976-625bf042924e
I only want "supplier", but this can be anything else. So it's possible for it to be:
http://localhost:3000/product/924511e8-9056-4c1e-9976-625bf042924e
Then I want "product"
But it can also be just http://localhost:3000/supplier/ also in this case I only want the supplier. And this can be anything.
How do I do this? If I've already tried it with pathname.slice(0, pathname.indexOf("/") but this doesn't seem to work.
So I only want the string after the http://localhost:3000/want this/ no matter if there is anything after it or not.
You can use the split method as below:
const url = 'http://localhost:3000/supplier/'
const want_this = url.split('/')[3]
Just use useParams from react router dom
import {useParams} from "react-router-dom";
function Child() {
// We can use the `useParams` hook here to access
// the dynamic pieces of the URL.
let { id } = useParams();
return (
<div>
<h3>ID: {id}</h3>
</div>
);
}

Conditional display of component based on Route matching

I am looking to conditionally render a component based on the route (using React Router), and the component should return null if it matches any path pre-defined in an array or some sort of similar data structure, where I do not have to be reliant on a <Switch>/<Route> setup. Currently here is what I have but it is clearly inefficient and not robust at all.
const Component = (props) => {
const path = props.location.pathname;
const paths_to_hide = ["/path/to/something", "/path/to/A", "/path/to/B"];
if (paths_to_hide.indexOf(path) != -1) return null;
return (
<div>test</div>
);
}
For example, if I want to match the following paths:
/path/to/something
/path/to/something/<any path that follows after this>
/path/<random string>/fixed
/newPath/<random string>
Note that this list is not just limited to 4 items, which is why I'm trying to stray away from having inline <Route> matching as I'm looking for a more scalable approach which I can save in a config file and have imported as an array or some similar data structure.
Currently my implementation will only be able to identify the first item, and there is no way to match the subsequent items, using the indexOf() function. What would be the best way to accomplish this? Any help is appreciated, thank you!
So upon reading the React Router docs further, I found this. This is definitely the most ideal solution and I overlooked this initially.
const Component = (props) => {
const path = props.location.pathname;
const paths_to_hide = ["/path/to/something", "/path/to/A", "/path/to/B"];
return (
<Switch>
<Route path={paths_to_hide}>
</Route>
<Route>
<div>test</div>
</Route>
</Switch>
);
}
So now I can create complex paths and don't have to loop through an array to match them, as it's taken care of by the Route component, and this is ideal because now I can import this array from a config file instead.

How to create routes with dynamic params in gatsbyjs [duplicate]

I have setup gatsby project using this link. It is working correctly.
Now I know how to create route by defining the component inside the pages folder. But now I have a new challenge I need to create one dynamic route so that I can pass my id in it (Just like reactjs).
<Route path: "/path/:id"/>
How do I do that in gatsby?
You have to explicitly tell gatsby that a path should be dynamic. From the docs:
// gatsby-node.js
// Implement the Gatsby API “onCreatePage”. This is
// called after every page is created.
exports.onCreatePage = async ({ page, actions }) => {
const { createPage } = actions
// page.matchPath is a special key that's used for matching pages
// only on the client.
if (page.path.match(/^\/app/)) {
page.matchPath = "/app/*"
// Update the page.
createPage(page)
}
}
and then you can use dynamic routing in src/pages/app.js
import { Router } from "#reach/router"
const SomeSubPage = props => {
return <div>Hi from SubPage with id: {props.id}</div>
}
const App = () => (
<Layout>
<Link to="/app/1">First item</Link>{" "}
<Link to="/app/2">Second item</Link>{" "}
<Router>
// ...dynamic routes here
<SomeSubPage path="/app/:id" />
</Router>
</Layout>
)
export default App
Everything that goes to /app/* will be handled dynamically now. You should find your id as usual in the props.
Have a look at their authentication example https://github.com/gatsbyjs/gatsby/tree/master/examples/simple-auth
You can use square brackets ([ ]) in the file path to mark any dynamic segments of the URL. For example, in order to edit a user, you might want a route like /user/:id to fetch the data for whatever id is passed into the URL.
src/pages/users/[id].js will generate a route like /users/:id
src/pages/users/[id]/group/[groupId].js will generate a route like /users/:id/group/:groupId
Reference: https://www.gatsbyjs.com/docs/reference/routing/file-system-route-api#creating-client-only-routes
You can use gatsby-plugin-create-client-paths. It uses matchPath. For more info check
https://www.gatsbyjs.org/docs/gatsby-internals-terminology/#matchpath
https://www.gatsbyjs.org/packages/gatsby-plugin-create-client-paths/
This answer is Super late, but for anyone in the future who is faced with this problem, I have a simpler solution.
In Gatsby terms it's called a Splat Route.
For examples, If you want some page "domain.com/profile/[id]", where id can be any number, which will be used to display different data inside the website, you should name your page as [...id].
Now inside the page you can access this id as
const ProfilePage = (props) => <div>This page is for id number {props.params.id}</div>
Note: Don't miss the 3 dots, that is what signifies a splat route in gatsby.

Meteor flow router and getting params of route in a react component

How do I get the params of a route inside a react component
Im using react containers from the react composer package
if this is the whole route
https://learnbuildrepeat-tevinthuku.c9users.io/ReadProjectMeta/wD98XTTtpf8ceyRJT
How do I get only
wD98XTTtpf8ceyRJT
and store its value in a variable inside a react component.
Ive tried to use
FlowRouter.getParam() but it doesnt work. I keep getting undefined
import React from 'react';
export default class ReadProjectMetaLayout extends React.Component {
render() {
var category = FlowRouter.getQueryParam();
console.log(category);
return (
<div>
<h4>Hello World</h4>
</div>
)
}
}
this is the route
FlowRouter.route("/ReadProjectMeta/:_id", {
name: 'project.meta',
action(params) {
mount(ReadProjectMetaLayoutContainer, {
components: (<ReadProjectMeta _id={params._id}/>)
})
}
});
What could be the problem and how do I solve it
To only get the last part of the string:
location.pathname.substr((location.pathname.lastIndexOf('/')+1))
Another pure meteor based thing you can try is from this reference:
FlowRouter.getParam(":_id");
NOTE: Your solution didn't work as you are getting query parameter, query parameters are the parameters that are passed in the url after '?'
i.e. /apps/this-is-my-app?show=yes&color=red
Here in above code color and show are query parameters, while apps is a part of pathname
FlowRouter.getParam(paramName) returns the value of a single URL
parameter
FlowRouter.getQueryParam(paramName) returns the value of a single URL query parameter
Reference:
https://guide.meteor.com/routing.html#accessing-route-info

Categories