I am writing a simple web app in React.
I’m trying to send data from one page to another using the useLocation hook in React Router, and I can’t seem to pass the data. For some reason, despite the value of un
changing, as shown by console logs, when I pass un
as a state to "/link-page"
, the value is passed as if no changes have been made. That is, the username displayed on the link page is simply 'h'
.
Here is my code:
Home.jsx:
import { Link } from "react-router-dom";
let un = 'h'
function handleChange() {
un = document.getElementById("username").value;
}
function Home() {
return (
<>
<h1>welcome to duel.fm!</h1>
<h3>enter your last.fm username below</h3>
<form>
<input type={"text"} id={"username"} onChange={handleChange} />
<Link to={"/link-page"} state={{ username: un }}>
<input type={"submit"} value={"submit"} />
</Link>
</form>
</>
)
}
export default Home;
LinkPage.jsx:
import { useLocation } from 'react-router-dom';
function LinkPage() {
const location = useLocation();
const username = location.state.username;
return (
<>
<h3>share this link with your friend!</h3>
<h5>{username}</h5>
</>
)
}
export default LinkPage;
2
Answers
Got it.
React doesn't care about the value of
un
, only the states of certain variables. Fixed it by usinguseState()
.Issue
un
andhandleChange
are declared outside the ReactTree, so no updates toh
will trigger React to rerender theHome
component so that a new "instance" ofhandleChange
is used with the updatedun
value.The form submission will also reload the page, so you’ll want to address that so that the data passed via the link persists through to the target route.
Solution
Move
un
andhandleChange
into theHome
component as React state and callback. The input should be fully controlled using the new state and setting avalue
prop.handleChange
should read the input value from theonChange
event object instead of usingdocument.getElementById
which is considered a React anti-pattern.Make the form button not a submit button.
If you wanted to use the form submission to navigate, then I’d recommend using the
useNavigate
hook and issuing a declarative navigation action.Example: