In the react component below I want to display the current value of a url query param after updating it. Something like this is straightforward to do with react-router, but I am trying to implement manually in a more minimal app. The code below effectively updates the url, but does not trigger a re-render, so the displayed value never updates.
export default function ExampleComponent() {
const params = new URLSearchParams(location.search);
const randomValue = params.get("random");
function updateRandomValue() {
const updatedValue = Math.random().toString();
const newURL = new URL(location.href);
newURL.searchParams.set("random", updatedValue);
history.pushState("", "", newURL);
}
return (
<>
<p>random value is {randomValue || "none"}</p>
<button onClick={updateRandomValue}>update new random value</button>
</>
);
}
Am I handling the navigation wrong? Does there need to be a useEffect
involved somehow? Is this functionality impossible without an outer component and/or some use of react state?
Figured it out after a little more noodling. Still need to get a better handle on the why, but changing the click handler from my original snippet to below resolves the bug, without needing additional state:
function updateRandomValue() {
const updatedValue = Math.random().toString();
params.set("random", updatedValue);
location.search = params.toString();
}
EDIT: Revisited this today and see it is wrong. It works but is forcing a browser refresh which is not what I want.
Another EDIT:
Not sure if this is considered a hack, but it accomplishes the ask and makes sense - duh, react components only rerender from state changes. In real life, the query param would most likely be used to change some other state, so this hack wouldn't be needed.
import {useState} from "react";
export default function ExampleComponent() {
const [, setForceUpdate] = useState({});
const urlParams = new URLSearchParams(location.search);
const randomValue = urlParams.get("random");
function updateRandomValue() {
const updatedValue = Math.random().toString();
const newURL = new URL(location.href);
newURL.searchParams.set("random", updatedValue);
history.pushState("", "", newURL);
setForceUpdate({});
}
return (
<div>
<p>Random value from URL: {randomValue}</p>
<button onClick={updateRandomValue}>Update Random Value</button>
</div>
);
}