How can I get the params from the url with React?
Solution 1
You can use withRouter
for getting router information such as location, history, path, and params.
import { withRouter } from "react-router-dom";
...
const VerifyAccount = withRouter(props) => {
const { token, email } = props.match.params;
console.log("toke, email: ", token, email) // And also show me how it looks!!!
...
}
And you should define your route like this.
<Route path='/verify-account/:token/:email' component={VerifyAccountPage} />
And you should call like this:
https://your-domain/verify-account/[token]/[email]
This will work.
Solution 2
Route match params are not the same thing as URL query string parameters.
You'll want to access the query string from the location object.
{ key: 'ac3df4', // not with HashHistory! pathname: '/somewhere', search: '?some=search-string', <-- query string hash: '#howdy', state: { [userDefined]: true } }
React-router-dom query parameters demo
They create a custom useQuery
hook:
const useQuery = () => new URLSearchParams(useLocation().search);
For your use case, on the page rendering the VerifyAccountPage
you want to then extract the query string parameters. Given path='/verify-account?token=:token&email=:email'
:
const query = useQuery();
const email = query.get('email');
const token = query.get('token');
Class-based component ?
If VerifyAccountPage
is a class-based component then you will need to access props.location
and process the query string yourself in a lifecycle method. This is because React hooks are only validly used by functional components.
componentDidMount() {
const { location } = this.props;
const query = new URLSearchParams(location.search);
const email = query.get('email');
const token = query.get('token');
...
}
Note regarding path
path='/verify-account?token=:token&email=:email'
The path params are only relevant in the path portion of a URL, you can't define params for the queryString portion of the URL. The above path is equivalent to path='/verify-account'
from react-router-dom
's perspective.
Related videos on Youtube
uberrebu
Updated on June 04, 2022Comments
-
uberrebu almost 2 years
I am trying to setup verify account with react and have the following in my
App.js
fileApp.js
import SigninPage from './pages/signin'; import ResetPasswordPage from './pages/resetPassword' import VerifyAccountPage from './pages/verifyAccount' ... ... import { useHistory } from 'react-router'; import { logout } from './utils/auth'; function App() { const history = useHistory(); return ( <Router> <Switch> <Route path='/' component={Home} exact /> <Route path="/signout" render={() => { logout(); history.push('/'); return null; }} /> <Route path='/signin' component={SigninPage} exact /> <Route path='/reset-password?reset-password-token=:resetPasswordToken' component={ResetPasswordPage} /> <Route path='/verify-account?token=:token&email=:email' component={VerifyAccountPage} exact /> </Switch> </Router> ); } export default App;
and in my VerifyAccountPage component have the following
import { Redirect } from 'react-router-dom'; import { useHistory } from 'react-router'; import { verifyAccount, isAuthenticated } from '../../utils/auth'; const VerifyAccount = () => { const { token, email } = this.props.match.params const history = useHistory(); const [error, setError] = useState(''); const handleGet = async (e) => { e.preventDefault(); setError(''); try { const data = await verifyAccount(token, email); if (data) { history.push('/'); } console.log(data); } catch (err) { if (err instanceof Error) { // handle errors thrown from frontend setError(err.message); } else { // handle errors thrown from backend setError(err); } } }; return isAuthenticated() ? ( <Redirect to="/#" /> ) : ( <> <Container> <FormWrap> <Icon to='/'>mywebsite</Icon> <FormContent> <Form action='#'> <FormH1>Verify Account</FormH1> <Text>Account has been verified!</Text> </Form> </FormContent> </FormWrap> </Container> </> ); }; export default VerifyAccount;
and here is
verifyAccount.js
pageimport React from 'react'; import VerifyAccount from '../components/VerifyAccount'; import ScrollToTop from '../components/ScrollToTop'; function VerifyAccountPage() { return ( <> <ScrollToTop /> <VerifyAccount /> </> ); } export default VerifyAccountPage;
here is
index.js
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') );
but this is not working and when I go to the link
https://mywebsite.com/verify-account?token=3heubek&[email protected]
nothing happens other than a 200 or 304 status codeno request is sent to the API so means that the params are not getting pulled out
can anyone point me to what is going on?
package versions used from package.json file
"dependencies": { "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.3.2", "@testing-library/user-event": "^7.1.2", "react": "^16.13.1", "react-dom": "^16.13.1", "react-icons": "^3.11.0", "react-router-dom": "^5.2.0", "react-scripts": "3.4.3", "react-scroll": "^1.8.1", "styled-components": "^5.2.0", "@types/node": "^15.6.0", "jwt-decode": "^3.0.0"
-
Slbox almost 3 yearsCan you please edit your question title to match the actual problem at hand? It's far too vague and open-ended as is. The core of your issue is with not being able to contact your API or not being able to read URL search parameters.
-
uberrebu almost 3 yearsit is not being able to access the search params...did you read question at all? read question first before asking to change it
-
Slbox almost 3 yearsI read it... I said it's about one thing or the other - API access or query parameter reading. Your title, "how do i setup verify account with react?" is a bad title because React doesn't verify accounts at all and the title doesn't actually reference the relevant library or the specific problem you're having
-
-
Cardoso almost 3 yearsCan you print the props with
console.log
and show me the result, please? -
uberrebu almost 3 yearslike this?
const VerifyAccount = (props) => { const { token, email } = props.match.params console.log({'token': token, 'email': email});
-
uberrebu almost 3 yearsi have that and nothing is getting logged to console even..so am not even sure what is going on..i only get 200 or 304 status code with no other logs
-
Cardoso almost 3 yearsI update my answer, can you show me the console log result?
-
uberrebu almost 3 yearsso i should have it like this?
const VerifyAccount = () => { const useQuery = () => new URLSearchParams(useLocation().search); const { token, email } = useQuery(); console.log({'token': token, 'email': email});
is this right? -
Drew Reese almost 3 years@uberrebu
useQuery
should be defined outside the component, but yes. -
Cardoso almost 3 yearsAnd please show me the location. I've updated my answer. Please have a look at it.
-
Cardoso almost 3 yearsLet us continue this discussion in chat.
-
uberrebu almost 3 yearswhat do you mean outside the component?
VerifyAccountPage
is a class-based component so you mind posting how everything should look like? i imported intop the App.js file likeimport VerifyAccountPage from './pages/verifyAccount' ...
i update the question to include this piece -
Drew Reese almost 3 years@uberrebu Please see the last section of my answer regarding class-based components. React hooks are incompatible with class-based components, so a
useQuery
hook won't work. -
uberrebu almost 3 yearsso what will be the solution to go with?
-
Drew Reese almost 3 years@uberrebu It seems you've a functional component, so I'd go with the first. If this isn't working then perhaps you've an issue with how you are rendering routes or linking to this path/page.
-
uberrebu almost 3 yearsyeah i posted most of all i have...page linking looks correct but maybe if you see anything off...first answer...am not even getting anything in console log
-
uberrebu almost 3 yearsthe usequery params from the codesandbox worked..thanks also