Reputation: 677
I have a React Router Link that calls a submitInput function when I click on it.
<Link onClick={submitInput} to={queryString}>Submit</Link>
This is what the submitInput function looks like. What it does is that it gets value from an input element and updates a state variable named QueryString.
function submitInput() {
var inputTCN = $('#inputTCN').val();
var finalString = "?name=" + inputTCN;
setQueryString(finalString);
}
This is what the state variable looks like.
const [queryString, setQueryString] = React.useState("?name=");
This is my problem. Let us say someone writes "hello" in the input element and clicks on Submit Link. The url changes to "?name=" and not "?name=hello". Let us say the input element is now changed to "hello2". The url changes to "?name=hello" and not "?name=hello2". And if the input element is changed to "hello3", the url changes to "?name=hello2" and not "?name=hello3".
The url parameter is always one step behind the state of QueryString. How do i prevent this?
PS: If I click the Submit Link twice, the url parameter and QueryString state will match.
Upvotes: 0
Views: 359
Reputation: 20765
Instead of a Link
you should use a simple span
(apply CSS to look it as anchor element).
<span onClick={submitInput}>Submit</span>
Then in your function,
function submitInput() {
var inputTCN = $('#inputTCN').val();
var finalString = "?name=" + inputTCN;
setQueryString(finalString);
props.history.push(finalString) //This will work
}
Another way is, using useEffect
hook,
React.useEffect(() => {
props.history.push(queryString)
}, [queryString])
Update
If you are using React Router V5.1
then you should be doing this,
// > V5.1
import { useHistory } from "react-router-dom";
export const YourFunctionName = () => {
const [queryString, setQueryString] = React.useState("?name=");
let history = useHistory();
function submitInput() {
var inputTCN = $('#inputTCN').val();
var finalString = "?name=" + inputTCN;
setQueryString(finalString);
}
React.useEffect(() => {
history.push(queryString)
}, [queryString])
return (
<div>
...
<span onClick={submitInput}>Submit</span>
...
</div>
);
};
Upvotes: 1
Reputation: 525
In order to prevent this, you could change your Link to something like a <span>
and then handle the url updating all in the submitInput
function.
Putting an onClick
on a Link
will fire both the function and the history (location) update at the same time. The Link is just an <a>
tag, so the browser is following the href (what "to" is converted to) when it is clicked. Your function also runs, but since that is doing a state update and will take some time, the href update has already occurred.
If instead you put the "href" logic into your function, you could achieve what you want. For example:
// update your link to a non linking element
<span onClick={submitInput}>Submit</span>
// and then force your url update at the end of the submitInput function
function submitInput() {
// existing logic
window.location.href = `?name=${finalString}`
}
Upvotes: 1