Querystring in react-router - reactjs

I am trying to set a Route path with a query string. Something in the lines of:
www.mywebsite.com/results?query1=:query1&query2=:query2&query3=:query3
I would than transition to the "Results" component like so:
<Route path="/" component={Main}>
<IndexRoute component={Home} />
<Route path="results?query1=:query1&query2=:query2&query3=:query3"
component={SearchResults} />
</Route>
In the SearchResults container I would like to be able to have access do query1, query2 and query3 params.
I have not been able to make it work. I get the following error:
bundle.js:22627 Warning: [react-router] Location
"/results?query1=1&query2=2&query3=3" did not match any routes
I tried following the steps in the following guide: (Section: What about query string parameters?)
https://www.themarketingtechnologist.co/react-router-an-introduction/
Can I get some help here?

If you are using React Router v2.xx, you can access the query parameters via the location.query object passed in to your Route component.
In other words, you could rework your route to look like the following:
<Route path="results" component={SearchResults} />
And then inside your SearchResults component, use this.props.location.query.query1 (similar for query2 and query3) to access the query parameter values.
EDIT: This is still the case for React Router v3.xx.

If you're using React Router >= v4 location.query is not available anymore. You can plug-in an external library (like https://www.npmjs.com/package/query-string), or use something like this:
const search = props.location.search; // could be '?foo=bar'
const params = new URLSearchParams(search);
const foo = params.get('foo'); // bar
(just keep in mind that URLSearchParams() is not supported by Internet Explorer)

Related

Create pages in gastby dynamically when you dont know the path

I want to create dynamic pages in gatsby but I don't know what the full url name would be.
createPage({
path: '/account/orders/:id',
matchPath: '/account/orders/:id',
component: path.resolve('./src/templates/order.tsx'),
});
I thought the code written would be okay to visit page with any value of 'id' but while building the development bundle it gives an error
account\orders\:id contains invalid WIN32 path characters
The ':id' value can be anything so I dont want to use looping method to create the page. What could be done?
Taking into account that:
You don't want to loop through pages
You will never know the value of the id
Your only chance is to use client-only routes through the file system route API.
In your case, assuming that your "unknown" page will be under /account/orders you should create a folder structure such: src/pages/account/orders/[...].js. The [...].js notation stands for the file system route for an undefined value.
In the [...].js file you can just create something like:
import React from "react"
import { Router } from "#reach/router"
import Layout from "../components/Layout"
import Profile from "../components/Profile"
import Default from "../components/Default"
import CustomOrderComponent from "../components/CustomOrderComponent"
const Orders = () => {
return (
<Layout>
<Router basepath="/account/orders">
<Profile path="/profile" />
<CustomOrderComponent path='/:id' />
<Default path="/" />
</Router>
</Layout>
)
}
export default Orders
From the docs:
Briefly, when a page loads, Reach Router looks at the path prop of
each component nested under <Router />, and chooses one to render
that best matches window.location (you can learn more about how
routing works from the #reach/router documentation). In the
case of the /orders/profile path, the Profile component will be
rendered, as its prefix matches the base path of /orders, and the
remaining part is identical to the child’s path.
In the above scenario, CustomOrderComponent will render your variable id (:id).

Can't get query parameter after changing from Router to HashRouter on React JS

This is the content of my app.json
I have the following state :
const params = new URLSearchParams(window.location.search)
const [checkboxes,setCheckkoxes] = React.useState({
circular: Number(params.has('circular')?params.get('circular'):0),
});
Its initial value is based on whether it has the param ('circular') on the URL.
<HashRouter basename = {process.env.PUBLIC_URL}>
<Switch>
<Route exact path = "/">
<Root/>
</Route>
<Route exact path = {"/Pesquisar/:searchField/:page"} component = {withRouter(Pesquisa)}>
</Route>
<Route exact path = {"/documento/:id"} component = {Documento}>
</Route>
<Route exact insecure component={ Insecure }/>
</Switch>
</HashRouter>
When I was using Router instead of HashRouter my state was working properly, when I pass the query param 'circular = 1' in the URL, my state was properly signalled to 1. However, after changing it to HashRouter it's not working anymore. Its value is always Zero. What's happening, why am I not able to access window.location.search params after switching from Router to HashRouter?
URLParams not able to work with react HashRouter that is a known issue wich is been reported on github.
In version v3.0.0-beta.1 they added two new props for complete customisations:
- getSearchParams: Function [optional]
Enables you to customise the evaluation of query-params-string from the url (or) any other source. If this function is not set, the library will use window.location.search as the search query-params-string for parsing selected-values. This can come handy if the URL is using hash values.
- setSearchParams: Function [optional]
Enables you to customise setting of the query params string in the url by providing the updated query-params-string as the function parameter. If this function is not set, the library will set the window.history via pushState method.
See docs

this.props.matches are not received when a route is loaded from <Match> in PreactJs

Following is my code. All the necessary imports like Match are present in the file.
app.js
<Match path="/">
if (path === '/registerParent') {
return (<div><RegisterParent path="/registerParent"/></div>);
}
</Match>
<Router>
<Route1 path="/route1"/>
<Route2 path="/route2"/>
</Router>
When I am routing the user to /registerParent using a button click, my route() function looks like this below :
routeUserToRegisterParent() {
route('/registerParent?id=12345');
}
12345 is attached to the route as a query parameter.
The problem is, when I execute above code, it throws following error as it cannot find this.props.matches in the props object :
Cannot read property id of undefined.
But when I load my route from <Router> instead of <Match>, it works properly and this.props.matches is also received.

How to use a wild card for BrowserRouter and a Phoenix project

I was hoping to get some help on understand how to use BrowserRouter with Phoenix. When I first created the project, I decided not to use any html (controllers/views) and fully depend on GraphQL/React. Resulting in my routes to be
pipeline :api do
plug :accepts, ["json"]
end
scope "/" do
pipe_through :api
forward "/api", Absinthe.Plug,
schema: HuntersWeb.Schema.Schema
forward "/graphiql", Absinthe.Plug.GraphiQL,
schema: HuntersWeb.Schema.Schema,
socket: HuntersWeb.UserSocket
end
The problem I'm getting is when I use BrowserRouter and for example try to access /signup, instead of the component being run I get a Cannot Get /signup. I was hoping to get some advice on how to use a wild card to solve this problem? Would I need to create a controller/view in order for it to work?
All help, advice and pointing in the right direction to better understand this approach and solution to the problem is appreciated :) If more information is needed please ask as well.
React Code
const App = () => (
<Router>
<Switch>
<Route exact path="/" component={Landing} />
<Route exact path="/signup" component={Signup} />
</Switch>
</Router>
);
UPDATE
Client.js
const HTTP_ENDPOINT = "http://localhost:4000/api";
const WS_ENDPOINT = "ws://localhost:4000/socket";
// Create an HTTP link to the Phoenix app's HTTP endpoint URL.
const httpLink = createHttpLink({
uri: HTTP_ENDPOINT
});
Config.exs
config :cors_plug,
origin: ["http://localhost:3000"],
max_age: 86400,
methods: ["GET", "POST"]

React router does not understand path variable?

I have a react applicatie running in a Amazon S3 bucket, it is available here: This is the homepage of the app, the user can search ships in the search bar.
The app produces a link in the dropdown menu that looks like this:
However when the user clicks on the link you don't see the details page but the user is redirected to this page without CSS.
Locally is everything working fine.
My route component looks like this:
export class Routes extends React.Component {
render() {
return (
<div>
<Route exact path={HOME_PAGE} component={Home}/>
<Route path={HOME_PAGE + "/details/:id"} component={Details}/>
<Route path={HOME_PAGE + "/form/:mode"} component={Edit}/>
<Route path={HOME_PAGE + "/form/:mode/:id"} component={Edit}/>
<Route path={HOME_PAGE + "/csvForm"} component={CsvForm}/>
</div>
);
}
}
I have build a prefix for the HOME_PAGE path that looks like this:
export const HOME_PAGE = (ENVIRONMENT == "DEVELOPMENT") ? "" : "/url"
This sets the homepage path for either development or production environment.
I was thinking of an other way to pass the ship id to the details page, maybe with a GET parameter. So the route will look something like this HOME_PAGE + /details?id=5c335682379b4d7a6ea454a8.
But I don't know if react-router supports that kind of parameter, maybe someone has a beter solution to solve this problem. Just by playing around on the website, I hope I have given enough information to understand the structure of the site.
If you're using react router v4, for every Route that you defined, react-router will pass three props:
Match
Location
History
If you would like to access the params (which is under /:someParams), you can access the Match props by using match.params.someParams
And if you prefer the query string, you can use the Location props by using location.search which is a string so that in your case it'll return ?id=5c335682379b4d7a6ea454a8. You'll have to process the string by using qs to get your id value.
You can see the detail over here: https://reacttraining.com/react-router/core/api/Route/route-props
So in your case this would be the solution:
On your parent
<Route path={HOME_PAGE + "/details"} component={Details}/>
Your your Details Component
import qs from 'query-string'
const Details = ({location}) => {
const {search} = location
const queries = qs.parse(search) // you should have the query string object
return (
<div>{queries.id}</div>
)
}

Resources