I'm trying to fetch the uid and token through the URL pathname using match
in my React app. But I got error:
Uncaught TypeError: n is undefined
and this is my code snippet:
const ResetPasswordConfirm = ( {match, reset_password_confirm} ) => {
...
const onSubmit = e=> {
e.preventDefault();
const uid = match.params.uid;
const token = match.params.token;
reset_password_confirm(uid, token, new_password, re_new_password);
setRequestSent(true);
};
};
According to this thread: https://stackoverflow.com/questions/70609785/uncaught-typeerror-match-is-undefined#:~:text=react-router-dom v5,render or children prop functions. It says it might have something to do with the version of react router, so I tried to use useParams(), but I found it hard to implement it...
I also tried to use matchPath, but I can find few examples.
Can anybody help me with this issue please?
Update:
react-router-dom version: 6.8.0
ResetPasswordConfirm is running in my container package.
import React, { useState } from "react";
import { Navigate, useParams } from 'react-router-dom';
import { connect } from 'react-redux';
import { reset_password_confirm } from '../actions/auth';
const ResetPasswordConfirm = ( {match, reset_password_confirm} ) => {
const [requestSent, setRequestSent] = useState(false);
const [formData, setFormData] = useState({
new_password: '',
re_new_password: ''
});
const { new_password, re_new_password } = formData;
const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value });
const onSubmit = e=> {
e.preventDefault();
const uid = match.params.uid;
const token = match.params.token;
reset_password_confirm(uid, token, new_password, re_new_password);
setRequestSent(true);
};
// Is the user sending the request?
// Redirect them to the home page
if (requestSent) {
return <Navigate to='/'/>
}
return (
<div className="container mt-5">
<form onSubmit={e => onSubmit(e)}>
{/* <div className="form-group">
<input className="form-control" type="email" placeholder="Email" name="email" value={email} onChange={e => onChange(e)} required></input>
</div>
<div className="form-group">
<input className="form-control" type="password" placeholder="Password" name="password" value={password} onChange={e => onChange(e)} minLength='6' required></input>
</div>
<button className="btn btn-primary" type="submit">Login</button> */}
<div className="form-group">
<label htmlFor="exampleInputPassword1">Password</label>
<input
type="password"
className="form-control"
id="exampleInputPassword1"
placeholder="New Password"
name="new_password"
value={new_password}
onChange={e => onChange(e)}
minLength='6'
required></input>
</div>
<div className="form-group">
<label htmlFor="exampleInputPassword1">Password</label>
<input
type="password"
className="form-control"
id="exampleInputPassword1"
placeholder="Confirm New Password"
name="re_new_password"
value={re_new_password}
onChange={e => onChange(e)}
minLength='6'
required></input>
</div>
<button type="submit" className="btn btn-primary">Reset Password</button>
</form>
</div>
);
};
export default connect(null, { reset_password_confirm }) (ResetPasswordConfirm);
Sorry for the lo-fi question. I will try to do better.
I tried to use useParams to fetch my uid
const onSubmit = e => {
...
let{uid} = useParams()
}
CodePudding user response:
There are no longer route props in react-router-dom
routed components, i.e. there is not any injected match
prop. You'll use the useParams
hook to access the route path params in RRDv6. You can't use React hooks in nested callbacks, they must be called in the function body of a React component or in custom React hooks. Use the useParams
hook in the component body and destructure the uid
and token
path params. Since you are using hooks you may as well also import and use the useNavigate
hook and issue the navigation action at the end of the form's onSubmit
handler instead of enqueueing a state update.
import React, { useState } from "react";
import { useParams, useNavigate } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { reset_password_confirm } from '../actions/auth';
const ResetPasswordConfirm = () => {
const dispatch = useDispatch();
const navigate = useNavigate();
const { uid, token } = useParams();
const [formData, setFormData] = useState({
new_password: '',
re_new_password: ''
});
const onChange = e => setFormData(formData => ({
...formData,
[e.target.name]: e.target.value
}));
const onSubmit = e => {
e.preventDefault();
const { new_password, re_new_password } = formData;
dispatch(reset_password_confirm(uid, token, new_password, re_new_password));
navigate("/");
};
return (
...
);
};
export default ResetPasswordConfirm;